diff --git a/KeywordSearch/solr/bin/autopsy-solr.cmd b/KeywordSearch/solr/bin/autopsy-solr.cmd
new file mode 100755
index 0000000000..018a626694
--- /dev/null
+++ b/KeywordSearch/solr/bin/autopsy-solr.cmd
@@ -0,0 +1,2032 @@
+@REM set JAVA_HOME=C:\Program Files\ojdkbuild\java-1.8.0-openjdk-1.8.0.222-1
+@REM set SOLR_SERVER_DIR=C:\Bitnami\solr-8.2.0-2/apache-solr/server
+set SOLR_PORT=8983
+set STOP_PORT=8079
+
+@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one or more
+@REM contributor license agreements. See the NOTICE file distributed with
+@REM this work for additional information regarding copyright ownership.
+@REM The ASF licenses this file to You under the Apache License, Version 2.0
+@REM (the "License"); you may not use this file except in compliance with
+@REM the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing, software
+@REM distributed under the License is distributed on an "AS IS" BASIS,
+@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@REM See the License for the specific language governing permissions and
+@REM limitations under the License.
+
+
+IF "%OS%"=="Windows_NT" setlocal enabledelayedexpansion enableextensions
+
+set "PASS_TO_RUN_EXAMPLE="
+
+REM Determine top-level Solr directory
+set SDIR=%~dp0
+IF "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1%
+set SOLR_TIP=%SDIR%\..
+pushd %SOLR_TIP%
+set SOLR_TIP=%CD%
+popd
+
+REM Used to report errors before exiting the script
+set SCRIPT_ERROR=
+set NO_USER_PROMPT=0
+
+REM Allow user to import vars from an include file
+REM vars set in the include file can be overridden with
+REM command line args
+IF "%SOLR_INCLUDE%"=="" set "SOLR_INCLUDE=%SOLR_TIP%\bin\autopsy-solr.in.cmd"
+IF EXIST "%SOLR_INCLUDE%" CALL "%SOLR_INCLUDE%"
+
+set "DEFAULT_SERVER_DIR=%SOLR_TIP%\server"
+
+REM Select HTTP OR HTTPS related configurations
+set SOLR_URL_SCHEME=http
+set "SOLR_JETTY_CONFIG=--module=http"
+set "SOLR_SSL_OPTS= "
+
+IF DEFINED SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dhadoop.security.credential.provider.path=%SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH%"
+)
+
+IF NOT DEFINED SOLR_SSL_ENABLED (
+ IF DEFINED SOLR_SSL_KEY_STORE (
+ set "SOLR_SSL_ENABLED=true"
+ ) ELSE (
+ set "SOLR_SSL_ENABLED=false"
+ )
+)
+
+IF "%SOLR_SSL_ENABLED%"=="true" (
+ set "SOLR_JETTY_CONFIG=--lib="%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*""
+ if !JAVA_MAJOR_VERSION! GEQ 9 (
+ set "SOLR_JETTY_CONFIG=!SOLR_JETTY_CONFIG! --module=https"
+ ) else (
+ set "SOLR_JETTY_CONFIG=!SOLR_JETTY_CONFIG! --module=https8"
+ )
+ set SOLR_URL_SCHEME=https
+ IF DEFINED SOLR_SSL_KEY_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%"
+ )
+
+ IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.type=%SOLR_SSL_KEY_STORE_TYPE%"
+ )
+
+ IF DEFINED SOLR_SSL_TRUST_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore=%SOLR_SSL_TRUST_STORE%"
+ )
+ IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.type=%SOLR_SSL_TRUST_STORE_TYPE%"
+ )
+
+ IF DEFINED SOLR_SSL_NEED_CLIENT_AUTH (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.ssl.needClientAuth=%SOLR_SSL_NEED_CLIENT_AUTH%"
+ )
+ IF DEFINED SOLR_SSL_WANT_CLIENT_AUTH (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.ssl.wantClientAuth=%SOLR_SSL_WANT_CLIENT_AUTH%"
+ )
+
+ IF DEFINED SOLR_SSL_CLIENT_KEY_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_CLIENT_KEY_STORE%"
+
+ IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_CLIENT_KEY_STORE_TYPE%"
+ )
+ ) ELSE (
+ IF DEFINED SOLR_SSL_KEY_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_KEY_STORE%"
+ )
+ IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_KEY_STORE_TYPE%"
+ )
+ )
+
+ IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_CLIENT_TRUST_STORE%"
+
+ IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_CLIENT_TRUST_STORE_TYPE%"
+ )
+ ) ELSE (
+ IF DEFINED SOLR_SSL_TRUST_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_TRUST_STORE%"
+ )
+ IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_TRUST_STORE_TYPE%"
+ )
+ )
+ IF DEFINED SOLR_SSL_CHECK_PEER_NAME (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.ssl.checkPeerName=%SOLR_SSL_CHECK_PEER_NAME%"
+ )
+) ELSE (
+ set SOLR_SSL_OPTS=
+)
+
+REM Authentication options
+
+IF NOT DEFINED SOLR_AUTH_TYPE (
+ IF DEFINED SOLR_AUTHENTICATION_OPTS (
+ echo WARNING: SOLR_AUTHENTICATION_OPTS variable configured without associated SOLR_AUTH_TYPE variable
+ echo Please configure SOLR_AUTH_TYPE variable with the authentication type to be used.
+ echo Currently supported authentication types are [kerberos, basic]
+ )
+)
+
+IF DEFINED SOLR_AUTH_TYPE (
+ IF DEFINED SOLR_AUTHENTICATION_CLIENT_BUILDER (
+ echo WARNING: SOLR_AUTHENTICATION_CLIENT_BUILDER and SOLR_AUTH_TYPE variables are configured together
+ echo Use SOLR_AUTH_TYPE variable to configure authentication type to be used
+ echo Currently supported authentication types are [kerberos, basic]
+ echo The value of SOLR_AUTHENTICATION_CLIENT_BUILDER configuration variable will be ignored
+ )
+)
+
+IF DEFINED SOLR_AUTH_TYPE (
+ IF /I "%SOLR_AUTH_TYPE%" == "basic" (
+ set SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"
+ ) ELSE (
+ IF /I "%SOLR_AUTH_TYPE%" == "kerberos" (
+ set SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"
+ ) ELSE (
+ echo ERROR: Value specified for SOLR_AUTH_TYPE configuration variable is invalid.
+ goto err
+ )
+ )
+)
+
+IF DEFINED SOLR_AUTHENTICATION_CLIENT_CONFIGURER (
+ echo WARNING: Found unsupported configuration variable SOLR_AUTHENTICATION_CLIENT_CONFIGURER
+ echo Please start using SOLR_AUTH_TYPE instead
+)
+IF DEFINED SOLR_AUTHENTICATION_CLIENT_BUILDER (
+ set AUTHC_CLIENT_BUILDER_ARG="-Dsolr.httpclient.builder.factory=%SOLR_AUTHENTICATION_CLIENT_BUILDER%"
+)
+set "AUTHC_OPTS=%AUTHC_CLIENT_BUILDER_ARG% %SOLR_AUTHENTICATION_OPTS%"
+
+REM Set the SOLR_TOOL_HOST variable for use when connecting to a running Solr instance
+IF NOT "%SOLR_HOST%"=="" (
+ set "SOLR_TOOL_HOST=%SOLR_HOST%"
+) ELSE (
+ set "SOLR_TOOL_HOST=localhost"
+)
+IF "%SOLR_JETTY_HOST%"=="" (
+ set SOLR_JETTY_HOST=0.0.0.0
+)
+
+REM Verify Java is available
+IF DEFINED SOLR_JAVA_HOME set "JAVA_HOME=%SOLR_JAVA_HOME%"
+REM Try to detect JAVA_HOME from the registry
+IF NOT DEFINED JAVA_HOME (
+ FOR /F "skip=2 tokens=2*" %%A IN ('REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment" /v CurrentVersion') DO set CurVer=%%B
+ FOR /F "skip=2 tokens=2*" %%A IN ('REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment\!CurVer!" /v JavaHome') DO (
+ set "JAVA_HOME=%%B"
+ )
+)
+IF NOT DEFINED JAVA_HOME goto need_java_home
+set JAVA_HOME=%JAVA_HOME:"=%
+IF %JAVA_HOME:~-1%==\ SET JAVA_HOME=%JAVA_HOME:~0,-1%
+IF NOT EXIST "%JAVA_HOME%\bin\java.exe" (
+ set "SCRIPT_ERROR=java.exe not found in %JAVA_HOME%\bin. Please set JAVA_HOME to a valid JRE / JDK directory."
+ goto err
+)
+set "JAVA=%JAVA_HOME%\bin\java"
+CALL :resolve_java_info
+IF !JAVA_MAJOR_VERSION! LSS 8 (
+ set "SCRIPT_ERROR=Java 1.8 or later is required to run Solr. Current Java version is: !JAVA_VERSION_INFO! (detected major: !JAVA_MAJOR_VERSION!)"
+ goto err
+)
+
+set FIRST_ARG=%1
+
+IF [%1]==[] goto usage
+
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="-h" goto usage
+IF "%1"=="--help" goto usage
+IF "%1"=="/?" goto usage
+IF "%1"=="-i" goto get_info
+IF "%1"=="-info" goto get_info
+IF "%1"=="status" goto get_info
+IF "%1"=="version" goto get_version
+IF "%1"=="-v" goto get_version
+IF "%1"=="-version" goto get_version
+IF "%1"=="assert" goto run_assert
+IF "%1"=="autoscaling" goto run_autoscaling
+
+REM Only allow the command to be the first argument, assume start if not supplied
+IF "%1"=="start" goto set_script_cmd
+IF "%1"=="stop" goto set_script_cmd
+IF "%1"=="restart" goto set_script_cmd
+IF "%1"=="healthcheck" (
+ REM healthcheck uses different arg parsing strategy
+ set SCRIPT_CMD=healthcheck
+ SHIFT
+ goto parse_healthcheck_args
+)
+IF "%1"=="create" (
+ set SCRIPT_CMD=create
+ SHIFT
+ goto parse_create_args
+)
+IF "%1"=="create_core" (
+ set SCRIPT_CMD=create_core
+ SHIFT
+ goto parse_create_args
+)
+IF "%1"=="create_collection" (
+ set SCRIPT_CMD=create_collection
+ SHIFT
+ goto parse_create_args
+)
+IF "%1"=="delete" (
+ set SCRIPT_CMD=delete
+ SHIFT
+ goto parse_delete_args
+)
+IF "%1"=="zk" (
+ set SCRIPT_CMD=zk
+ SHIFT
+ set ZK_RECURSE=false
+ goto parse_zk_args
+)
+IF "%1"=="auth" (
+ set SCRIPT_CMD=auth
+ SHIFT
+ goto run_auth
+)
+IF "%1"=="config" (
+ REM config uses different arg parsing strategy
+ set SCRIPT_CMD=config
+ SHIFT
+ set CONFIG_ARGS=
+ goto parse_config_args
+)
+
+goto parse_args
+
+:usage
+IF NOT "%SCRIPT_ERROR%"=="" ECHO %SCRIPT_ERROR%
+IF [%FIRST_ARG%]==[] goto script_usage
+IF "%FIRST_ARG%"=="-help" goto script_usage
+IF "%FIRST_ARG%"=="-usage" goto script_usage
+IF "%FIRST_ARG%"=="-h" goto script_usage
+IF "%FIRST_ARG%"=="--help" goto script_usage
+IF "%FIRST_ARG%"=="/?" goto script_usage
+IF "%SCRIPT_CMD%"=="start" goto start_usage
+IF "%SCRIPT_CMD%"=="restart" goto start_usage
+IF "%SCRIPT_CMD%"=="stop" goto stop_usage
+IF "%SCRIPT_CMD%"=="healthcheck" goto healthcheck_usage
+IF "%SCRIPT_CMD%"=="create" goto create_usage
+IF "%SCRIPT_CMD%"=="create_core" goto create_core_usage
+IF "%SCRIPT_CMD%"=="create_collection" goto create_collection_usage
+IF "%SCRIPT_CMD%"=="delete" goto delete_usage
+IF "%SCRIPT_CMD%"=="zk" goto zk_usage
+IF "%SCRIPT_CMD%"=="auth" goto auth_usage
+IF "%SCRIPT_CMD%"=="status" goto status_usage
+goto done
+
+:script_usage
+@echo.
+@echo Usage: solr COMMAND OPTIONS
+@echo where COMMAND is one of: start, stop, restart, healthcheck, create, create_core, create_collection, delete, version, zk, auth, assert, config, autoscaling
+@echo.
+@echo Standalone server example (start Solr running in the background on port 8984):
+@echo.
+@echo solr start -p 8984
+@echo.
+@echo SolrCloud example (start Solr running in SolrCloud mode using localhost:2181 to connect to Zookeeper, with 1g max heap size and remote Java debug options enabled):
+@echo.
+@echo solr start -c -m 1g -z localhost:2181 -a "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044"
+@echo.
+@echo Omit '-z localhost:2181' from the above command if you have defined ZK_HOST in solr.in.cmd.
+@echo.
+@echo Pass -help after any COMMAND to see command-specific usage information,
+@echo such as: solr start -help or solr stop -help
+@echo.
+goto done
+
+:start_usage
+@echo.
+@echo Usage: solr %SCRIPT_CMD% [-f] [-c] [-h hostname] [-p port] [-d directory] [-z zkHost] [-m memory] [-e example] [-s solr.solr.home] [-t solr.data.home] [-a "additional-options"] [-V]
+@echo.
+@echo -f Start Solr in foreground; default starts Solr in the background
+@echo and sends stdout / stderr to solr-PORT-console.log
+@echo.
+@echo -c or -cloud Start Solr in SolrCloud mode; if -z not supplied and ZK_HOST not defined in
+@echo solr.in.cmd, an embedded ZooKeeper instance is started on Solr port+1000,
+@echo such as 9983 if Solr is bound to 8983
+@echo.
+@echo -h host Specify the hostname for this Solr instance
+@echo.
+@echo -p port Specify the port to start the Solr HTTP listener on; default is 8983
+@echo " The specified port (SOLR_PORT) will also be used to determine the stop port"
+@echo " STOP_PORT=(\$SOLR_PORT-1000) and JMX RMI listen port RMI_PORT=(\$SOLR_PORT+10000). "
+@echo " For instance, if you set -p 8985, then the STOP_PORT=7985 and RMI_PORT=18985"
+@echo.
+@echo -d dir Specify the Solr server directory; defaults to server
+@echo.
+@echo -z zkHost Zookeeper connection string; only used when running in SolrCloud mode using -c
+@echo If neither ZK_HOST is defined in solr.in.cmd nor the -z parameter is specified,
+@echo an embedded ZooKeeper instance will be launched.
+@echo.
+@echo -m memory Sets the min (-Xms) and max (-Xmx) heap size for the JVM, such as: -m 4g
+@echo results in: -Xms4g -Xmx4g; by default, this script sets the heap size to 512m
+@echo.
+@echo -s dir Sets the solr.solr.home system property; Solr will create core directories under
+@echo this directory. This allows you to run multiple Solr instances on the same host
+@echo while reusing the same server directory set using the -d parameter. If set, the
+@echo specified directory should contain a solr.xml file, unless solr.xml exists in Zookeeper.
+@echo This parameter is ignored when running examples (-e), as the solr.solr.home depends
+@echo on which example is run. The default value is server/solr. If passed a relative dir
+@echo validation with the current dir will be done before trying the default server/^
+@echo.
+@echo -t dir Sets the solr.data.home system property, where Solr will store index data in ^/data subdirectories.
+@echo If not set, Solr uses solr.solr.home for both config and data.
+@echo.
+@echo -e example Name of the example to run; available examples:
+@echo cloud: SolrCloud example
+@echo techproducts: Comprehensive example illustrating many of Solr's core capabilities
+@echo dih: Data Import Handler
+@echo schemaless: Schema-less example
+@echo.
+@echo -a opts Additional parameters to pass to the JVM when starting Solr, such as to setup
+@echo Java debug options. For example, to enable a Java debugger to attach to the Solr JVM
+@echo you could pass: -a "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=18983"
+@echo In most cases, you should wrap the additional parameters in double quotes.
+@echo.
+@echo -j opts Additional parameters to pass to Jetty when starting Solr.
+@echo For example, to add configuration folder that jetty should read
+@echo you could pass: -j "--include-jetty-dir=/etc/jetty/custom/server/"
+@echo In most cases, you should wrap the additional parameters in double quotes.
+@echo.
+@echo -noprompt Don't prompt for input; accept all defaults when running examples that accept user input
+@echo.
+@echo -v and -q Verbose (-v) or quiet (-q) logging. Sets default log level to DEBUG or WARN instead of INFO
+@echo.
+@echo -V/-verbose Verbose messages from this script
+@echo.
+goto done
+
+:status_usage
+@echo.
+@echo Usage: solr status
+@echo.
+@echo NOTE: This command will show the status of all running Solr servers
+@echo.
+goto done
+
+:stop_usage
+@echo.
+@echo Usage: solr stop [-k key] [-p port] [-V]
+@echo.
+@echo -k key Stop key; default is solrrocks
+@echo.
+@echo -p port Specify the port the Solr HTTP listener is bound to
+@echo.
+@echo -all Find and stop all running Solr servers on this host
+@echo.
+@echo -V/-verbose Verbose messages from this script
+@echo.
+@echo NOTE: To see if any Solr servers are running, do: solr status
+@echo.
+goto done
+
+:healthcheck_usage
+@echo.
+@echo Usage: solr healthcheck [-c collection] [-z zkHost] [-V]
+@echo.
+@echo Can be run from remote (non-Solr^) hosts, as long as a proper ZooKeeper connection is provided
+@echo.
+@echo -c collection Collection to run healthcheck against.
+@echo.
+@echo -z zkHost Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.cmd;
+@echo otherwise, default is localhost:9983
+@echo.
+@echo -V Enable more verbose output
+@echo.
+goto done
+
+:create_usage
+echo.
+echo Usage: solr create [-c name] [-d confdir] [-n confname] [-shards #] [-replicationFactor #] [-p port] [-V]
+echo.
+echo Create a core or collection depending on whether Solr is running in standalone (core) or SolrCloud
+echo mode (collection). In other words, this action detects which mode Solr is running in, and then takes
+echo the appropriate action (either create_core or create_collection). For detailed usage instructions, do:
+echo.
+echo bin\solr create_core -help
+echo.
+echo or
+echo.
+echo bin\solr create_collection -help
+echo.
+goto done
+
+:delete_usage
+echo.
+echo Usage: solr delete [-c name] [-deleteConfig true^|false] [-p port] [-V]
+echo.
+echo Deletes a core or collection depending on whether Solr is running in standalone (core) or SolrCloud
+echo mode (collection). If you're deleting a collection in SolrCloud mode, the default behavior is to also
+echo delete the configuration directory from Zookeeper so long as it is not being used by another collection.
+echo You can override this behavior by passing -deleteConfig false when running this command.
+echo.
+echo Can be run on remote (non-Solr^) hosts, as long as a valid SOLR_HOST is provided in solr.in.cmd
+echo.
+echo -c name Name of core to delete
+echo.
+echo -deleteConfig boolean Delete the configuration directory from Zookeeper; default is true
+echo.
+echo -p port Port of a local Solr instance where you want to delete the core/collection
+echo If not specified, the script will search the local system for a running
+echo Solr instance and will use the port of the first server it finds.
+echo.
+echo -V Enables more verbose output.
+echo.
+goto done
+
+:create_core_usage
+echo.
+echo Usage: solr create_core [-c ^] [-d confdir] [-p port] [-V]
+echo.
+echo When a configSet is used, this can be run from any host. If pointing at a non-configSet directory, this
+echo must be run from the host that you wish to create the core on.
+echo.
+echo -c ^ Name of core to create
+echo.
+echo -d confdir Configuration directory to copy when creating the new core, built-in options are:
+echo.
+echo _default: Minimal configuration, which supports enabling/disabling field-guessing support
+echo sample_techproducts_configs: Example configuration with many optional features enabled to
+echo demonstrate the full power of Solr
+echo.
+echo If not specified, default is: _default
+echo.
+echo Alternatively, you can pass the path to your own configuration directory instead of using
+echo one of the built-in configurations, such as: bin\solr create_core -c mycore -d c:/tmp/myconfig
+echo.
+echo -p port Port of a local Solr instance where you want to create the new core
+echo If not specified, the script will search the local system for a running
+echo Solr instance and will use the port of the first server it finds.
+echo.
+echo -V Enable more verbose output.
+echo.
+goto done
+
+:create_collection_usage
+echo.
+echo Usage: solr create_collection [-c collection] [-d confdir] [-n confname] [-shards #] [-replicationFactor #] [-p port] [-V]
+echo.
+echo Can be run from remote (non-Solr^) hosts, as long as a valid SOLR_HOST is provided in solr.in.cmd.
+echo.
+echo -c ^ Name of collection to create
+echo.
+echo -d ^ Configuration directory to copy when creating the new collection, built-in options are:
+echo.
+echo _default: Minimal configuration, which supports enabling/disabling field-guessing support
+echo sample_techproducts_configs: Example configuration with many optional features enabled to
+echo demonstrate the full power of Solr
+echo.
+echo If not specified, default is: _default
+echo.
+echo Alternatively, you can pass the path to your own configuration directory instead of using
+echo one of the built-in configurations, such as: bin\solr create_collection -c mycoll -d c:/tmp/myconfig
+echo.
+echo By default the script will upload the specified confdir directory into Zookeeper using the same
+echo name as the collection (-c) option. Alternatively, if you want to reuse an existing directory
+echo or create a confdir in Zookeeper that can be shared by multiple collections, use the -n option
+echo.
+echo -n configName Name the configuration directory in Zookeeper; by default, the configuration
+echo will be uploaded to Zookeeper using the collection name (-c), but if you want
+echo to use an existing directory or override the name of the configuration in
+echo Zookeeper, then use the -c option.
+echo.
+echo -shards # Number of shards to split the collection into; default is 1
+echo.
+echo -replicationFactor # Number of copies of each document in the collection, default is 1 (no replication)
+echo.
+echo -p port Port of a local Solr instance where you want to create the new collection
+echo If not specified, the script will search the local system for a running
+echo Solr instance and will use the port of the first server it finds.
+echo.
+echo -V Enable more verbose output.
+echo.
+goto done
+
+:zk_usage
+set ZK_FULL=true
+goto zk_short_usage
+:zk_full_usage
+echo Can be run on remote (non-Solr^) hosts, as long as valid ZK_HOST information is provided.
+echo Be sure to check the Solr logs in case of errors.
+echo.
+echo -z zkHost Optional Zookeeper connection string for all commands. If specified it
+echo overrides the 'ZK_HOST=...'' defined in solr.in.cmd.
+echo.
+echo -V Enable more verbose output.
+echo.
+echo upconfig uploads a configset from the local machine to Zookeeper. (Backcompat: -upconfig)
+echo.
+echo downconfig downloads a configset from Zookeeper to the local machine. (Backcompat: -downconfig)
+echo.
+echo -n configName Name of the configset in Zookeeper that will be the destination of
+echo 'upconfig' and the source for 'downconfig'.
+echo.
+echo -d confdir The local directory the configuration will be uploaded from for
+echo 'upconfig' or downloaded to for 'downconfig'. If 'confdir' is a child of
+echo ...solr/server/solr/configsets' then the configs will be copied from/to
+echo that directory. Otherwise it is interpreted as a simple local path.
+echo.
+echo cp copies files or folders to/from Zookeeper or Zokeeper -^> Zookeeper
+echo -r Recursively copy ^ to ^. Command will fail if ^ has children and
+echo -r is not specified. Optional
+echo.
+echo. ^, ^ : [file:][/]path/to/local/file or zk:/path/to/zk/node
+echo NOTE: ^ and ^ may both be Zookeeper resources prefixed by 'zk:'
+echo When ^ is a zk resource, ^ may be '.'
+echo If ^ ends with '/', then ^ will be a local folder or parent znode and the last
+echo element of the ^ path will be appended unless ^ also ends in a slash.
+echo ^ may be zk:, which may be useful when using the cp -r form to backup/restore
+echo the entire zk state.
+echo You must enclose local paths that end in a wildcard in quotes or just
+echo end the local path in a slash. That is,
+echo 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181' is equivalent to
+echo 'bin/solr zk cp -r ^"/some/dir/*^" zk:/ -z localhost:2181'
+echo but 'bin/solr zk cp -r /some/dir/* zk:/ -z localhost:2181' will throw an error.
+echo.
+echo Here's an example of backup/restore for a ZK configuration:
+echo to copy to local: 'bin/solr zk cp -r zk:/ /some/dir -z localhost:2181'
+echo to restore to ZK: 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181'
+echo.
+echo The 'file:' prefix is stripped, thus 'file:/wherever' specifies an absolute local path and
+echo 'file:somewhere' specifies a relative local path. All paths on Zookeeper are absolute.
+echo.
+echo Zookeeper nodes CAN have data, so moving a single file to a parent znode
+echo will overlay the data on the parent Znode so specifying the trailing slash
+echo can be important.
+echo.
+echo Wildcards are supported when copying from local, trailing only and must be quoted.
+echo.
+echo rm deletes files or folders on Zookeeper
+echo -r Recursively delete if ^ is a directory. Command will fail if ^
+echo has children and -r is not specified. Optional
+echo ^ : [zk:]/path/to/zk/node. ^ may not be the root ('/')
+echo.
+echo mv moves (renames) znodes on Zookeeper
+echo ^, ^ : Zookeeper nodes, the 'zk:' prefix is optional.
+echo If ^ ends with '/', then ^ will be a parent znode
+echo and the last element of the ^ path will be appended.
+echo Zookeeper nodes CAN have data, so moving a single file to a parent znode
+echo will overlay the data on the parent Znode so specifying the trailing slash
+echo is important.
+echo.
+echo ls lists the znodes on Zookeeper
+echo -r recursively descends the path listing all znodes. Optional
+echo ^: The Zookeeper path to use as the root.
+echo.
+echo Only the node names are listed, not data
+echo.
+echo mkroot makes a znode in Zookeeper with no data. Can be used to make a path of arbitrary
+echo depth but primarily intended to create a 'chroot'.
+echo.
+echo ^: The Zookeeper path to create. Leading slash is assumed if not present.
+echo Intermediate nodes are created as needed if not present.
+echo.
+
+goto done
+
+:zk_short_usage
+IF NOT "!ERROR_MSG!"=="" (
+ echo ERROR: !ERROR_MSG!
+ echo.
+)
+echo Usage: solr zk upconfig^|downconfig -d ^ -n ^ [-z zkHost]
+echo solr zk cp [-r] ^ ^ [-z zkHost]
+echo solr zk rm [-r] ^ [-z zkHost]
+echo solr zk mv ^ ^ [-z zkHost]
+echo solr zk ls [-r] ^ [-z zkHost]
+echo solr zk mkroot ^ [-z zkHost]
+echo.
+IF "%ZK_FULL%"=="true" (
+ goto zk_full_usage
+) ELSE (
+ echo Type bin/solr zk -help for full usage help
+)
+goto done
+
+:auth_usage
+echo Usage: solr auth enable [-type basicAuth] -credentials user:pass [-blockUnknown ^] [-updateIncludeFileOnly ^] [-V]
+echo solr auth enable [-type basicAuth] -prompt ^ [-blockUnknown ^] [-updateIncludeFileOnly ^] [-V]
+echo solr auth disable [-updateIncludeFileOnly ^] [-V]
+echo.
+echo Updates or enables/disables authentication. Must be run on the machine hosting Solr.
+echo.
+echo -type ^ The authentication mechanism to enable. Defaults to 'basicAuth'.
+echo.
+echo -credentials ^ The username and password of the initial user
+echo Note: only one of -prompt or -credentials must be provided
+echo.
+echo -prompt ^ Prompts the user to provide the credentials
+echo Note: only one of -prompt or -credentials must be provided
+echo.
+echo -blockUnknown ^ When true, this blocks out access to unauthenticated users. When not provided,
+echo this defaults to false (i.e. unauthenticated users can access all endpoints, except the
+echo operations like collection-edit, security-edit, core-admin-edit etc.^). Check the reference
+echo guide for Basic Authentication for more details.
+echo.
+echo -updateIncludeFileOnly ^ Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
+echo authentication (i.e. don't update security.json^)"
+echo.
+echo -z zkHost Zookeeper connection string. Unnecessary if ZK_HOST is defined in solr.in.cmd.
+echo.
+echo -d ^ Specify the Solr server directory"
+echo.
+echo -s ^ Specify the Solr home directory. This is where any credentials or authentication"
+echo configuration files (e.g. basicAuth.conf^) would be placed."
+echo.
+echo -V Enable more verbose output
+echo.
+goto done
+
+REM Really basic command-line arg parsing
+:parse_args
+
+set "arg=%~1"
+set "firstTwo=%arg:~0,2%"
+IF "%SCRIPT_CMD%"=="" set SCRIPT_CMD=start
+IF [%1]==[] goto process_script_cmd
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+IF "%1"=="-f" goto set_foreground_mode
+IF "%1"=="-foreground" goto set_foreground_mode
+IF "%1"=="-V" goto set_verbose
+IF "%1"=="-verbose" goto set_verbose
+IF "%1"=="-v" goto set_debug
+IF "%1"=="-q" goto set_warn
+IF "%1"=="-c" goto set_cloud_mode
+IF "%1"=="-cloud" goto set_cloud_mode
+IF "%1"=="-d" goto set_server_dir
+IF "%1"=="-dir" goto set_server_dir
+IF "%1"=="-s" goto set_solr_home_dir
+IF "%1"=="-t" goto set_solr_data_dir
+IF "%1"=="-solr.home" goto set_solr_home_dir
+IF "%1"=="-e" goto set_example
+IF "%1"=="-example" goto set_example
+IF "%1"=="-h" goto set_host
+IF "%1"=="-host" goto set_host
+IF "%1"=="-m" goto set_memory
+IF "%1"=="-memory" goto set_memory
+IF "%1"=="-p" goto set_port
+IF "%1"=="-port" goto set_port
+IF "%1"=="-z" goto set_zookeeper
+IF "%1"=="-zkhost" goto set_zookeeper
+IF "%1"=="-zkHost" goto set_zookeeper
+IF "%1"=="-a" goto set_addl_opts
+IF "%1"=="-addlopts" goto set_addl_opts
+IF "%1"=="-j" goto set_addl_jetty_config
+IF "%1"=="-jettyconfig" goto set_addl_jetty_config
+IF "%1"=="-noprompt" goto set_noprompt
+IF "%1"=="-k" goto set_stop_key
+IF "%1"=="-key" goto set_stop_key
+IF "%1"=="-all" goto set_stop_all
+IF "%firstTwo%"=="-D" goto set_passthru
+IF NOT "%1"=="" goto invalid_cmd_line
+goto invalid_cmd_line
+
+:set_script_cmd
+set SCRIPT_CMD=%1
+SHIFT
+goto parse_args
+
+:set_foreground_mode
+set FG=1
+SHIFT
+goto parse_args
+
+:set_verbose
+set verbose=1
+set "PASS_TO_RUN_EXAMPLE=--verbose !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+goto parse_args
+
+:set_debug
+set SOLR_LOG_LEVEL=DEBUG
+SHIFT
+goto parse_args
+
+:set_warn
+set SOLR_LOG_LEVEL=WARN
+SHIFT
+goto parse_args
+
+:set_cloud_mode
+set SOLR_MODE=solrcloud
+SHIFT
+goto parse_args
+
+:set_server_dir
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Directory name is required!
+ goto invalid_cmd_line
+)
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected directory but found %2 instead!
+ goto invalid_cmd_line
+)
+
+REM See if they are using a short-hand name relative from the Solr tip directory
+IF EXIST "%SOLR_TIP%\%~2" (
+ set "SOLR_SERVER_DIR=%SOLR_TIP%\%~2"
+) ELSE (
+ set "SOLR_SERVER_DIR=%~2"
+)
+SHIFT
+SHIFT
+goto parse_args
+
+:set_solr_home_dir
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Directory name is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected directory but found %2 instead!
+ goto invalid_cmd_line
+)
+set "SOLR_HOME=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_solr_data_dir
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Directory name is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected directory but found %2 instead!
+ goto invalid_cmd_line
+)
+set "SOLR_DATA_HOME=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_example
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Example name is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected example name but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set EXAMPLE=%~2
+SHIFT
+SHIFT
+goto parse_args
+
+:set_memory
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Memory setting is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected memory setting but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set SOLR_HEAP=%~2
+set "PASS_TO_RUN_EXAMPLE=-m %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_host
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Hostname is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected hostname but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set SOLR_HOST=%~2
+set "PASS_TO_RUN_EXAMPLE=-h %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_port
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Port is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected port but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set SOLR_PORT=%~2
+set "PASS_TO_RUN_EXAMPLE=-p %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_stop_key
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Stop key is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected stop key but found %2 instead!
+ goto invalid_cmd_line
+)
+set STOP_KEY=%~2
+SHIFT
+SHIFT
+goto parse_args
+
+:set_stop_all
+set STOP_ALL=1
+SHIFT
+goto parse_args
+
+:set_zookeeper
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Zookeeper connection string is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected Zookeeper connection string but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set "ZK_HOST=%~2"
+set "PASS_TO_RUN_EXAMPLE=-z %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_addl_opts
+set "arg=%~2"
+set "SOLR_ADDL_ARGS=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_addl_jetty_config
+set "arg=%~2"
+set "SOLR_JETTY_ADDL_CONFIG=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_passthru
+set "PASSTHRU=%~1=%~2"
+IF NOT "%SOLR_OPTS%"=="" (
+ set "SOLR_OPTS=%SOLR_OPTS% %PASSTHRU%"
+) ELSE (
+ set "SOLR_OPTS=%PASSTHRU%"
+)
+set "PASS_TO_RUN_EXAMPLE=%PASSTHRU% !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_noprompt
+set NO_USER_PROMPT=1
+set "PASS_TO_RUN_EXAMPLE=-noprompt !PASS_TO_RUN_EXAMPLE!"
+
+SHIFT
+goto parse_args
+
+REM Perform the requested command after processing args
+:process_script_cmd
+
+IF "%verbose%"=="1" (
+ CALL :safe_echo "Using Solr root directory: %SOLR_TIP%"
+ CALL :safe_echo "Using Java: %JAVA%"
+ "%JAVA%" -version
+ @echo.
+)
+
+IF NOT "%SOLR_HOST%"=="" (
+ set SOLR_HOST_ARG=-Dhost=%SOLR_HOST%
+) ELSE (
+ set SOLR_HOST_ARG=
+)
+
+IF "%SOLR_SERVER_DIR%"=="" set "SOLR_SERVER_DIR=%DEFAULT_SERVER_DIR%"
+
+IF NOT EXIST "%SOLR_SERVER_DIR%" (
+ set "SCRIPT_ERROR=Solr server directory %SOLR_SERVER_DIR% not found!"
+ goto err
+)
+
+IF NOT "%EXAMPLE%"=="" goto run_example
+
+:start_solr
+IF "%SOLR_HOME%"=="" set "SOLR_HOME=%SOLR_SERVER_DIR%\solr"
+IF EXIST "%cd%\%SOLR_HOME%" set "SOLR_HOME=%cd%\%SOLR_HOME%"
+
+IF NOT EXIST "%SOLR_HOME%\" (
+ IF EXIST "%SOLR_SERVER_DIR%\%SOLR_HOME%" (
+ set "SOLR_HOME=%SOLR_SERVER_DIR%\%SOLR_HOME%"
+ ) ELSE (
+ set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% not found!"
+ goto err
+ )
+)
+
+IF "%STOP_KEY%"=="" set STOP_KEY=solrrocks
+
+@REM This is quite hacky, but examples rely on a different log4j2.xml
+@REM so that we can write logs for examples to %SOLR_HOME%\..\logs
+@REM IF [%SOLR_LOGS_DIR%] == [] (
+@REM set "SOLR_LOGS_DIR=%SOLR_SERVER_DIR%\logs"
+@REM ) ELSE (
+@REM set SOLR_LOGS_DIR=%SOLR_LOGS_DIR:"=%
+@REM )
+
+set "SOLR_LOGS_DIR=%APPDATA%\autopsy\var\log\solr"
+
+set "EXAMPLE_DIR=%SOLR_TIP%\example"
+set TMP_SOLR_HOME=!SOLR_HOME:%EXAMPLE_DIR%=!
+IF NOT "%TMP_SOLR_HOME%"=="%SOLR_HOME%" (
+ set "SOLR_LOGS_DIR=%SOLR_HOME%\..\logs"
+ set "LOG4J_CONFIG=file:///%SOLR_SERVER_DIR%\resources\log4j2.xml"
+)
+
+set IS_RESTART=0
+IF "%SCRIPT_CMD%"=="restart" (
+ IF "%SOLR_PORT%"=="" (
+ set "SCRIPT_ERROR=Must specify the port when trying to restart Solr."
+ goto err
+ )
+ set SCRIPT_CMD=stop
+ set IS_RESTART=1
+)
+
+@REM stop logic here
+IF "%SCRIPT_CMD%"=="stop" (
+ IF "%SOLR_PORT%"=="" (
+ IF "%STOP_ALL%"=="1" (
+ set found_it=0
+ for /f "usebackq" %%i in (`dir /b "%SOLR_LOGS_DIR%" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ @REM j is the ip:port and k is the pid
+ IF NOT "%%k"=="0" (
+ IF "%%j"=="%SOLR_JETTY_HOST%:!SOME_SOLR_PORT!" (
+ set found_it=1
+ @echo Stopping Solr process %%k running on port !SOME_SOLR_PORT!
+ IF "%STOP_PORT%"=="" set /A STOP_PORT=!SOME_SOLR_PORT! - 1000
+ "%JAVA%" %SOLR_SSL_OPTS% -Djetty.home="%SOLR_SERVER_DIR%" -jar "%SOLR_SERVER_DIR%\start.jar" STOP.PORT=!STOP_PORT! STOP.KEY=%STOP_KEY% --stop
+ del "%SOLR_LOGS_DIR%"\solr-!SOME_SOLR_PORT!.port
+ timeout /T 5
+ REM Kill it if it is still running after the graceful shutdown
+ For /f "tokens=2,5" %%M in ('netstat -nao ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF "%%N"=="%%k" (
+ IF "%%M"=="%SOLR_JETTY_HOST%:!SOME_SOLR_PORT!" (
+ @echo Forcefully killing process %%N
+ taskkill /f /PID %%N
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ if "!found_it!"=="0" echo No Solr nodes found to stop.
+ ) ELSE (
+ set "SCRIPT_ERROR=Must specify the port when trying to stop Solr, or use -all to stop all running nodes on this host."
+ goto err
+ )
+ ) ELSE (
+ set found_it=0
+ For /f "tokens=2,5" %%M in ('netstat -nao ^| find "TCP " ^| find ":0 " ^| find ":%SOLR_PORT% "') do (
+ IF NOT "%%N"=="0" (
+ IF "%%M"=="%SOLR_JETTY_HOST%:%SOLR_PORT%" (
+ set found_it=1
+ @echo Stopping Solr process %%N running on port %SOLR_PORT%
+ IF "%STOP_PORT%"=="" set /A STOP_PORT=%SOLR_PORT% - 1000
+ "%JAVA%" %SOLR_SSL_OPTS% -Djetty.home="%SOLR_SERVER_DIR%" -jar "%SOLR_SERVER_DIR%\start.jar" %SOLR_JETTY_CONFIG% STOP.PORT=!STOP_PORT! STOP.KEY=%STOP_KEY% --stop
+ del "%SOLR_LOGS_DIR%"\solr-%SOLR_PORT%.port
+ timeout /T 5
+ REM Kill it if it is still running after the graceful shutdown
+ For /f "tokens=2,5" %%j in ('netstat -nao ^| find "TCP " ^| find ":0 " ^| find ":%SOLR_PORT% "') do (
+ IF "%%N"=="%%k" (
+ IF "%%j"=="%SOLR_JETTY_HOST%:%SOLR_PORT%" (
+ @echo Forcefully killing process %%N
+ taskkill /f /PID %%N
+ )
+ )
+ )
+ )
+ )
+ )
+ if "!found_it!"=="0" echo No Solr found running on port %SOLR_PORT%
+ )
+
+ IF "!IS_RESTART!"=="0" goto done
+)
+
+IF "!IS_RESTART!"=="1" set SCRIPT_CMD=start
+
+IF "%SOLR_PORT%"=="" set SOLR_PORT=8983
+IF "%STOP_PORT%"=="" set /A STOP_PORT=%SOLR_PORT% - 1000
+
+IF "%SCRIPT_CMD%"=="start" (
+ REM see if Solr is already running using netstat
+ For /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":%SOLR_PORT% "') do (
+ IF NOT "%%k"=="0" (
+ IF "%%j"=="%SOLR_JETTY_HOST%:%SOLR_PORT%" (
+ set "SCRIPT_ERROR=Process %%k is already listening on port %SOLR_PORT%. If this is Solr, please stop it first before starting (or use restart). If this is not Solr, then please choose a different port using -p PORT"
+ goto err
+ )
+ )
+ )
+)
+
+@REM determine if -server flag is supported by current JVM
+"%JAVA%" -server -version > nul 2>&1
+IF ERRORLEVEL 1 (
+ set IS_JDK=false
+ set "SERVEROPT="
+ @echo WARNING: You are using a JRE without support for -server option. Please upgrade to latest JDK for best performance
+ @echo.
+) ELSE (
+ set IS_JDK=true
+ set "SERVEROPT=-server"
+)
+if !JAVA_MAJOR_VERSION! LSS 9 (
+ "%JAVA%" -d64 -version > nul 2>&1
+ IF ERRORLEVEL 1 (
+ set "IS_64BIT=false"
+ @echo WARNING: 32-bit Java detected. Not recommended for production. Point your JAVA_HOME to a 64-bit JDK
+ @echo.
+ ) ELSE (
+ set IS_64bit=true
+ )
+) ELSE (
+ set IS_64bit=true
+)
+
+REM Clean up and rotate logs. Default to false since 7.4 as log4j2 handles startup rotation
+IF [%SOLR_LOG_PRESTART_ROTATION%] == [] (
+ set SOLR_LOG_PRESTART_ROTATION=false
+)
+IF [%SOLR_LOG_PRESTART_ROTATION%] == [true] (
+ REM Enable any of these if you require old remove/archive behavior
+ REM call :run_utils "-remove_old_solr_logs 7" || echo "Failed removing old solr logs"
+ REM call :run_utils "-archive_gc_logs" || echo "Failed archiving old GC logs"
+ REM call :run_utils "-archive_console_logs" || echo "Failed archiving old console logs"
+ call :run_utils "-rotate_solr_logs 9" || echo "Failed rotating old solr logs"
+)
+
+IF NOT "%ZK_HOST%"=="" set SOLR_MODE=solrcloud
+
+IF "%SOLR_MODE%"=="solrcloud" (
+ IF "%ZK_CLIENT_TIMEOUT%"=="" set "ZK_CLIENT_TIMEOUT=15000"
+
+ set "CLOUD_MODE_OPTS=-DzkClientTimeout=!ZK_CLIENT_TIMEOUT!"
+
+ IF NOT "%ZK_HOST%"=="" (
+ set "CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -DzkHost=%ZK_HOST%"
+ ) ELSE (
+ IF "%verbose%"=="1" echo Configuring SolrCloud to launch an embedded Zookeeper using -DzkRun
+ set "CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -DzkRun"
+ )
+ IF EXIST "%SOLR_HOME%\collection1\core.properties" set "CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -Dbootstrap_confdir=./solr/collection1/conf -Dcollection.configName=myconf -DnumShards=1"
+) ELSE (
+ set CLOUD_MODE_OPTS=
+ IF NOT EXIST "%SOLR_HOME%\solr.xml" (
+ set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% must contain solr.xml!"
+ goto err
+ )
+)
+
+REM These are useful for attaching remove profilers like VisualVM/JConsole
+IF "%ENABLE_REMOTE_JMX_OPTS%"=="true" (
+ IF "!RMI_PORT!"=="" set RMI_PORT=1%SOLR_PORT%
+ set REMOTE_JMX_OPTS=-Dcom.sun.management.jmxremote ^
+-Dcom.sun.management.jmxremote.local.only=false ^
+-Dcom.sun.management.jmxremote.ssl=false ^
+-Dcom.sun.management.jmxremote.authenticate=false ^
+-Dcom.sun.management.jmxremote.port=!RMI_PORT! ^
+-Dcom.sun.management.jmxremote.rmi.port=!RMI_PORT!
+
+ IF NOT "%SOLR_HOST%"=="" set REMOTE_JMX_OPTS=%REMOTE_JMX_OPTS% -Djava.rmi.server.hostname=%SOLR_HOST%
+) ELSE (
+ set REMOTE_JMX_OPTS=
+)
+
+IF NOT "%SOLR_HEAP%"=="" set SOLR_JAVA_MEM=-Xms%SOLR_HEAP% -Xmx%SOLR_HEAP%
+IF "%SOLR_JAVA_MEM%"=="" set SOLR_JAVA_MEM=-Xms512m -Xmx512m
+IF "%SOLR_JAVA_STACK_SIZE%"=="" set SOLR_JAVA_STACK_SIZE=-Xss256k
+set SOLR_OPTS=%SOLR_JAVA_STACK_SIZE% %SOLR_OPTS%
+IF "%SOLR_TIMEZONE%"=="" set SOLR_TIMEZONE=UTC
+
+IF "%GC_TUNE%"=="" (
+ set GC_TUNE=-XX:+UseG1GC ^
+ -XX:+PerfDisableSharedMem ^
+ -XX:+ParallelRefProcEnabled ^
+ -XX:MaxGCPauseMillis=250 ^
+ -XX:+UseLargePages ^
+ -XX:+AlwaysPreTouch
+)
+
+if !JAVA_MAJOR_VERSION! GEQ 9 (
+ IF NOT "%GC_LOG_OPTS%"=="" (
+ echo ERROR: On Java 9 you cannot set GC_LOG_OPTS, only default GC logging is available. Exiting
+ GOTO :eof
+ )
+ set GC_LOG_OPTS="-Xlog:gc*:file=\"!SOLR_LOGS_DIR!\solr_gc.log\":time,uptime:filecount=9,filesize=20M"
+) else (
+ IF "%GC_LOG_OPTS%"=="" (
+ rem Set defaults for Java 8
+ set GC_LOG_OPTS=-verbose:gc ^
+ -XX:+PrintHeapAtGC ^
+ -XX:+PrintGCDetails ^
+ -XX:+PrintGCDateStamps ^
+ -XX:+PrintGCTimeStamps ^
+ -XX:+PrintTenuringDistribution ^
+ -XX:+PrintGCApplicationStoppedTime
+ )
+ if "%JAVA_VENDOR%" == "IBM J9" (
+ set GC_LOG_OPTS=!GC_LOG_OPTS! "-Xverbosegclog:!SOLR_LOGS_DIR!\solr_gc.log" -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=9 -XX:GCLogFileSize=20M
+ ) else (
+ set GC_LOG_OPTS=!GC_LOG_OPTS! "-Xloggc:!SOLR_LOGS_DIR!\solr_gc.log" -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=9 -XX:GCLogFileSize=20M
+ )
+)
+
+IF "%verbose%"=="1" (
+ @echo Starting Solr using the following settings:
+ CALL :safe_echo " JAVA = %JAVA%"
+ CALL :safe_echo " SOLR_SERVER_DIR = %SOLR_SERVER_DIR%"
+ CALL :safe_echo " SOLR_HOME = %SOLR_HOME%"
+ @echo SOLR_HOST = %SOLR_HOST%
+ @echo SOLR_PORT = %SOLR_PORT%
+ @echo STOP_PORT = %STOP_PORT%
+ @echo SOLR_JAVA_MEM = %SOLR_JAVA_MEM%
+ @echo GC_TUNE = !GC_TUNE!
+ @echo GC_LOG_OPTS = %GC_LOG_OPTS%
+ @echo SOLR_TIMEZONE = %SOLR_TIMEZONE%
+
+ IF "%SOLR_MODE%"=="solrcloud" (
+ @echo CLOUD_MODE_OPTS = %CLOUD_MODE_OPTS%
+ )
+
+ IF NOT "%SOLR_OPTS%"=="" (
+ @echo SOLR_OPTS = %SOLR_OPTS%
+ )
+
+ IF NOT "%SOLR_ADDL_ARGS%"=="" (
+ CALL :safe_echo " SOLR_ADDL_ARGS = %SOLR_ADDL_ARGS%"
+ )
+
+ IF NOT "%SOLR_JETTY_ADDL_CONFIG%"=="" (
+ CALL :safe_echo " SOLR_JETTY_ADDL_CONFIG = %SOLR_JETTY_ADDL_CONFIG%"
+ )
+
+ IF "%ENABLE_REMOTE_JMX_OPTS%"=="true" (
+ @echo RMI_PORT = !RMI_PORT!
+ @echo REMOTE_JMX_OPTS = %REMOTE_JMX_OPTS%
+ )
+
+ IF NOT "%SOLR_LOG_LEVEL%"=="" (
+ @echo SOLR_LOG_LEVEL = !SOLR_LOG_LEVEL!
+ )
+
+ IF NOT "%SOLR_DATA_HOME%"=="" (
+ @echo SOLR_DATA_HOME = !SOLR_DATA_HOME!
+ )
+
+ @echo.
+)
+
+set START_OPTS=-Duser.timezone=%SOLR_TIMEZONE%
+set START_OPTS=%START_OPTS% !GC_TUNE! %GC_LOG_OPTS%
+IF NOT "!CLOUD_MODE_OPTS!"=="" set "START_OPTS=%START_OPTS% !CLOUD_MODE_OPTS!"
+IF NOT "%REMOTE_JMX_OPTS%"=="" set "START_OPTS=%START_OPTS% %REMOTE_JMX_OPTS%"
+IF NOT "%SOLR_ADDL_ARGS%"=="" set "START_OPTS=%START_OPTS% %SOLR_ADDL_ARGS%"
+IF NOT "%SOLR_HOST_ARG%"=="" set "START_OPTS=%START_OPTS% %SOLR_HOST_ARG%"
+IF NOT "%SOLR_OPTS%"=="" set "START_OPTS=%START_OPTS% %SOLR_OPTS%"
+IF "%SOLR_SSL_ENABLED%"=="true" (
+ set "SSL_PORT_PROP=-Dsolr.jetty.https.port=%SOLR_PORT%"
+ set "START_OPTS=%START_OPTS% %SOLR_SSL_OPTS% !SSL_PORT_PROP!"
+)
+IF NOT "%SOLR_LOG_LEVEL%"=="" set "START_OPTS=%START_OPTS% -Dsolr.log.level=%SOLR_LOG_LEVEL%"
+
+set SOLR_LOGS_DIR_QUOTED="%SOLR_LOGS_DIR%"
+set SOLR_DATA_HOME_QUOTED="%SOLR_DATA_HOME%"
+
+set "START_OPTS=%START_OPTS% -Dsolr.log.dir=%SOLR_LOGS_DIR_QUOTED%"
+IF NOT "%SOLR_DATA_HOME%"=="" set "START_OPTS=%START_OPTS% -Dsolr.data.home=%SOLR_DATA_HOME_QUOTED%"
+IF NOT DEFINED LOG4J_CONFIG set "LOG4J_CONFIG=file:///%SOLR_SERVER_DIR%\resources\log4j2.xml"
+
+cd /d "%SOLR_SERVER_DIR%"
+
+IF NOT EXIST "%SOLR_LOGS_DIR%" (
+ mkdir "%SOLR_LOGS_DIR%"
+)
+copy /Y NUL "%SOLR_LOGS_DIR%\.writable" > NUL 2>&1 && set WRITEOK=1
+IF DEFINED WRITEOK (
+ del "%SOLR_LOGS_DIR%\.writable"
+) else (
+ echo "ERROR: Logs directory %SOLR_LOGS_DIR% is not writable or could not be created. Exiting"
+ GOTO :eof
+)
+echo " contexts etc lib modules resources scripts solr solr-webapp " > "%TEMP%\solr-pattern.txt"
+findstr /i /C:" %SOLR_LOGS_DIR% " "%TEMP%\solr-pattern.txt" 1>nul
+if %ERRORLEVEL% == 0 (
+ echo "ERROR: Logs directory %SOLR_LOGS_DIR% is invalid. Reserved for the system. Exiting"
+ GOTO :eof
+)
+
+IF NOT EXIST "%SOLR_LOGS_DIR%\tmp" (
+ mkdir "%SOLR_LOGS_DIR%\tmp"
+)
+
+IF "%DEFAULT_CONFDIR%"=="" set "DEFAULT_CONFDIR=%SOLR_SERVER_DIR%\solr\configsets\_default\conf"
+
+IF "%FG%"=="1" (
+ REM run solr in the foreground
+ title "Solr-%SOLR_PORT%"
+ echo %SOLR_PORT%>"%SOLR_LOGS_DIR%"\solr-%SOLR_PORT%.port
+ "%JAVA%" %SERVEROPT% %SOLR_JAVA_MEM% %START_OPTS% ^
+ -Dlog4j.configurationFile="%LOG4J_CONFIG%" -DSTOP.PORT=!STOP_PORT! -DSTOP.KEY=%STOP_KEY% ^
+ -Dsolr.solr.home="%SOLR_HOME%" -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%" ^
+ -Djetty.host=%SOLR_JETTY_HOST% -Djetty.port=%SOLR_PORT% -Djetty.home="%SOLR_SERVER_DIR%" ^
+ -Djava.io.tmpdir="%SOLR_LOGS_DIR%\tmp" -jar start.jar %SOLR_JETTY_CONFIG% "%SOLR_JETTY_ADDL_CONFIG%"
+) ELSE (
+ START /B "Solr-%SOLR_PORT%" /D "%SOLR_SERVER_DIR%" ^
+ "%JAVA%" %SERVEROPT% %SOLR_JAVA_MEM% %START_OPTS% ^
+ -Dlog4j.configurationFile="%LOG4J_CONFIG%" -DSTOP.PORT=!STOP_PORT! -DSTOP.KEY=%STOP_KEY% ^
+ -Dsolr.log.muteconsole ^
+ -Dsolr.solr.home="%SOLR_HOME%" -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%" ^
+ -Djetty.host=%SOLR_JETTY_HOST% -Djetty.port=%SOLR_PORT% -Djetty.home="%SOLR_SERVER_DIR%" ^
+ -Djava.io.tmpdir="%SOLR_LOGS_DIR%\tmp" -jar start.jar %SOLR_JETTY_CONFIG% "%SOLR_JETTY_ADDL_CONFIG%" > "!SOLR_LOGS_DIR!\solr-%SOLR_PORT%-console.log"
+ echo %SOLR_PORT%>"%SOLR_LOGS_DIR%"\solr-%SOLR_PORT%.port
+
+ REM now wait to see Solr come online ...
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%"^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI status -maxWaitSecs 30 -solr !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:%SOLR_PORT%/solr
+)
+
+goto done
+
+:run_example
+REM Run the requested example
+
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI run_example -script "%SDIR%\solr.cmd" -e %EXAMPLE% -d "%SOLR_SERVER_DIR%" ^
+ -urlScheme !SOLR_URL_SCHEME! !PASS_TO_RUN_EXAMPLE!
+
+REM End of run_example
+goto done
+
+:get_info
+REM Find all Java processes, correlate with those listening on a port
+REM and then try to contact via that port using the status tool
+for /f "usebackq" %%i in (`dir /b "%SOLR_LOGS_DIR%" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" (
+ if "%%j"=="%SOLR_JETTY_HOST%:!SOME_SOLR_PORT!" (
+ @echo.
+ set has_info=1
+ echo Found Solr process %%k running on port !SOME_SOLR_PORT!
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI status -solr !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!SOME_SOLR_PORT!/solr
+ @echo.
+ )
+ )
+ )
+ )
+)
+if NOT "!has_info!"=="1" echo No running Solr nodes found.
+set has_info=
+goto done
+
+:parse_healthcheck_args
+IF [%1]==[] goto run_healthcheck
+IF "%1"=="-V" goto set_healthcheck_verbose
+IF "%1"=="-c" goto set_healthcheck_collection
+IF "%1"=="-collection" goto set_healthcheck_collection
+IF "%1"=="-z" goto set_healthcheck_zk
+IF "%1"=="-zkhost" goto set_healthcheck_zk
+IF "%1"=="-zkHost" goto set_healthcheck_zk
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+goto run_healthcheck
+
+:set_healthcheck_verbose
+set HEALTHCHECK_VERBOSE="-verbose"
+SHIFT
+goto parse_healthcheck_args
+
+:set_healthcheck_collection
+set HEALTHCHECK_COLLECTION=%~2
+SHIFT
+SHIFT
+goto parse_healthcheck_args
+
+:set_healthcheck_zk
+set ZK_HOST=%~2
+SHIFT
+SHIFT
+goto parse_healthcheck_args
+
+:run_healthcheck
+IF NOT DEFINED HEALTHCHECK_COLLECTION goto healthcheck_usage
+IF NOT DEFINED HEALTHCHECK_VERBOSE set "HEALTHCHECK_VERBOSE="
+IF NOT DEFINED HEALTHCHECK_ZK_HOST set "HEALTHCHECK_ZK_HOST=localhost:9983"
+echo ZK_HOST: !ZK_HOST!
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI healthcheck -collection !HEALTHCHECK_COLLECTION! -zkHost !ZK_HOST! %HEALTHCHECK_VERBOSE%
+goto done
+
+:run_assert
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI %*
+if errorlevel 1 (
+ exit /b 1
+)
+goto done
+
+:run_autoscaling
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI %*
+goto done
+
+:parse_config_args
+IF [%1]==[] goto run_config
+IF "%1"=="-z" goto set_config_zk
+IF "%1"=="-zkhost" goto set_config_zk
+IF "%1"=="-zkHost" goto set_config_zk
+IF "%1"=="-s" goto set_config_url_scheme
+IF "%1"=="-scheme" goto set_config_url_scheme
+set "CONFIG_ARGS=!CONFIG_ARGS! %1"
+SHIFT
+goto parse_config_args
+
+:set_config_zk
+set ZK_HOST=%~2
+SHIFT
+SHIFT
+goto parse_config_args
+
+:set_config_url_scheme
+set SOLR_URL_SCHEME=%~2
+SHIFT
+SHIFT
+goto parse_config_args
+
+:run_config
+IF NOT "!ZK_HOST!"=="" SET "CONFIG_ARGS=!CONFIG_ARGS! -z !ZK_HOST!"
+IF NOT "!SOLR_URL_SCHEME!"=="" SET "CONFIG_ARGS=!CONFIG_ARGS! -scheme !SOLR_URL_SCHEME!"
+
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI config !CONFIG_ARGS!
+if errorlevel 1 (
+ exit /b 1
+)
+goto done
+
+:get_version
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI version
+goto done
+
+:run_utils
+set "TOOL_CMD=%~1"
+set q="-q"
+IF "%verbose%"=="1" set q=""
+"%JAVA%" %SOLR_SSL_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI utils -s "%DEFAULT_SERVER_DIR%" -l "%SOLR_LOGS_DIR%" %q:"=% %TOOL_CMD%
+if errorlevel 1 (
+ exit /b 1
+)
+goto done
+
+:parse_create_args
+IF [%1]==[] goto run_create
+IF "%1"=="-V" goto set_create_verbose
+IF "%1"=="-c" goto set_create_name
+IF "%1"=="-core" goto set_create_name
+IF "%1"=="-collection" goto set_create_name
+IF "%1"=="-d" goto set_create_confdir
+IF "%1"=="-confdir" goto set_create_confdir
+IF "%1"=="-n" goto set_create_confname
+IF "%1"=="-confname" goto set_create_confname
+IF "%1"=="-s" goto set_create_shards
+IF "%1"=="-shards" goto set_create_shards
+IF "%1"=="-rf" goto set_create_rf
+IF "%1"=="-replicationFactor" goto set_create_rf
+IF "%1"=="-p" goto set_create_port
+IF "%1"=="-port" goto set_create_port
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+goto run_create
+
+
+:set_create_verbose
+set CREATE_VERBOSE="-verbose"
+SHIFT
+goto parse_create_args
+
+:set_create_name
+set CREATE_NAME=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_confdir
+set CREATE_CONFDIR=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_confname
+set CREATE_CONFNAME=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_port
+set CREATE_PORT=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_shards
+set CREATE_NUM_SHARDS=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_rf
+set CREATE_REPFACT=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:run_create
+IF "!CREATE_NAME!"=="" (
+ set "SCRIPT_ERROR=Name (-c) is a required parameter for %SCRIPT_CMD%"
+ goto invalid_cmd_line
+)
+IF NOT DEFINED CREATE_VERBOSE set "CREATE_VERBOSE="
+IF "!CREATE_CONFDIR!"=="" set CREATE_CONFDIR=_default
+IF "!CREATE_NUM_SHARDS!"=="" set CREATE_NUM_SHARDS=1
+IF "!CREATE_REPFACT!"=="" set CREATE_REPFACT=1
+IF "!CREATE_CONFNAME!"=="" set CREATE_CONFNAME=!CREATE_NAME!
+
+REM Find a port that Solr is running on
+if "!CREATE_PORT!"=="" (
+ for /f "usebackq" %%i in (`dir /b "%SOLR_LOGS_DIR%" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" set CREATE_PORT=!SOME_SOLR_PORT!
+ )
+ )
+ )
+)
+if "!CREATE_PORT!"=="" (
+ set "SCRIPT_ERROR=Could not find a running Solr instance on this host! Please use the -p option to specify the port."
+ goto err
+)
+
+if "!CREATE_CONFDIR!"=="_default" (
+ echo WARNING: Using _default configset with data driven schema functionality. NOT RECOMMENDED for production use.
+ echo To turn off: bin\solr config -c !CREATE_NAME! -p !CREATE_PORT! -action set-user-property -property update.autoCreateFields -value false
+)
+
+if "%SCRIPT_CMD%"=="create_core" (
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI create_core -name !CREATE_NAME! -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!CREATE_PORT!/solr ^
+ -confdir !CREATE_CONFDIR! -configsetsDir "%SOLR_TIP%\server\solr\configsets" %CREATE_VERBOSE%
+) else (
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%"^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI create -name !CREATE_NAME! -shards !CREATE_NUM_SHARDS! -replicationFactor !CREATE_REPFACT! ^
+ -confname !CREATE_CONFNAME! -confdir !CREATE_CONFDIR! -configsetsDir "%SOLR_TIP%\server\solr\configsets" ^
+ -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!CREATE_PORT!/solr %CREATE_VERBOSE%
+)
+
+goto done
+
+:parse_delete_args
+IF [%1]==[] goto run_delete
+IF "%1"=="-V" goto set_delete_verbose
+IF "%1"=="-c" goto set_delete_name
+IF "%1"=="-core" goto set_delete_name
+IF "%1"=="-collection" goto set_delete_name
+IF "%1"=="-p" goto set_delete_port
+IF "%1"=="-port" goto set_delete_port
+IF "%1"=="-deleteConfig" goto set_delete_config
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+goto run_delete
+
+:set_delete_verbose
+set DELETE_VERBOSE="-verbose"
+SHIFT
+goto parse_delete_args
+
+:set_delete_name
+set DELETE_NAME=%~2
+SHIFT
+SHIFT
+goto parse_delete_args
+
+:set_delete_port
+set DELETE_PORT=%~2
+SHIFT
+SHIFT
+goto parse_delete_args
+
+:set_delete_config
+set DELETE_CONFIG=%~2
+SHIFT
+SHIFT
+goto parse_delete_args
+
+:run_delete
+IF NOT DEFINED DELETE_VERBOSE set "DELETE_VERBOSE="
+IF "!DELETE_NAME!"=="" (
+ set "SCRIPT_ERROR=Name (-c) is a required parameter for %SCRIPT_CMD%"
+ goto invalid_cmd_line
+)
+
+REM Find a port that Solr is running on
+if "!DELETE_PORT!"=="" (
+ for /f "usebackq" %%i in (`dir /b "%SOLR_LOGS_DIR%" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" set DELETE_PORT=!SOME_SOLR_PORT!
+ )
+ )
+ )
+)
+if "!DELETE_PORT!"=="" (
+ set "SCRIPT_ERROR=Could not find a running Solr instance on this host! Please use the -p option to specify the port."
+ goto err
+)
+
+if "!DELETE_CONFIG!"=="" (
+ set DELETE_CONFIG=true
+)
+
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+-Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+-classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+org.apache.solr.util.SolrCLI delete -name !DELETE_NAME! -deleteConfig !DELETE_CONFIG! ^
+-solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!DELETE_PORT!/solr %DELETE_VERBOSE%
+
+goto done
+
+REM Clumsy to do the state machine thing for -d and -n, but that's required for back-compat
+:parse_zk_args
+IF "%1"=="-upconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="-V" (
+ goto set_zk_verbose
+) ELSE IF "%1"=="upconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="-downconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="downconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="cp" (
+ goto set_zk_op
+) ELSE IF "%1"=="mv" (
+ goto set_zk_op
+) ELSE IF "%1"=="rm" (
+ goto set_zk_op
+) ELSE IF "%1"=="ls" (
+ goto set_zk_op
+) ELSE IF "%1"=="mkroot" (
+ goto set_zk_op
+) ELSE IF "%1"=="-n" (
+ goto set_config_name
+) ELSE IF "%1"=="-r" (
+ goto set_zk_recurse
+) ELSE IF "%1"=="-configname" (
+ goto set_config_name
+) ELSE IF "%1"=="-d" (
+ goto set_configdir
+) ELSE IF "%1"=="-confdir" (
+ goto set_configdir
+) ELSE IF "%1"=="-z" (
+ goto set_config_zk
+) ELSE IF "%1"=="/?" (
+ goto zk_usage
+) ELSE IF "%1"=="-h" (
+ goto zk_usage
+) ELSE IF "%1"=="-help" (
+ goto zk_usage
+) ELSE IF "!ZK_SRC!"=="" (
+ if not "%~1"=="" (
+ goto set_zk_src
+ )
+) ELSE IF "!ZK_DST!"=="" (
+ IF "%ZK_OP%"=="cp" (
+ goto set_zk_dst
+ )
+ IF "%ZK_OP%"=="mv" (
+ goto set_zk_dst
+ )
+ set ZK_DST="_"
+) ELSE IF NOT "%1"=="" (
+ set ERROR_MSG="Unrecognized or misplaced zk argument %1%"
+ goto zk_short_usage
+)
+goto run_zk
+
+:set_zk_op
+set ZK_OP=%~1
+SHIFT
+goto parse_zk_args
+
+:set_zk_verbose
+set ZK_VERBOSE="-verbose"
+SHIFT
+goto parse_zk_args
+
+:set_config_name
+set CONFIGSET_NAME=%~2
+SHIFT
+SHIFT
+goto parse_zk_args
+
+:set_configdir
+set CONFIGSET_DIR=%~2
+SHIFT
+SHIFT
+goto parse_zk_args
+
+:set_config_zk
+set ZK_HOST=%~2
+SHIFT
+SHIFT
+goto parse_zk_args
+
+:set_zk_src
+set ZK_SRC=%~1
+SHIFT
+goto parse_zk_args
+
+:set_zk_dst
+set ZK_DST=%~1
+SHIFT
+goto parse_zk_args
+
+:set_zk_recurse
+set ZK_RECURSE="true"
+SHIFT
+goto parse_zk_args
+
+:run_zk
+IF "!ZK_OP!"=="" (
+ set "ERROR_MSG=Invalid command specified for zk sub-command"
+ goto zk_short_usage
+)
+
+IF "!ZK_HOST!"=="" (
+ set "ERROR_MSG=Must specify -z zkHost"
+ goto zk_short_usage
+)
+
+IF "!ZK_OP!"=="-upconfig" (
+ set ZK_OP="upconfig"
+)
+IF "!ZK_OP!"=="-downconfig" (
+ set ZK_OP="downconfig"
+)
+
+IF "!ZK_OP!"=="upconfig" (
+ IF "!CONFIGSET_NAME!"=="" (
+ set ERROR_MSG="-n option must be set for upconfig"
+ goto zk_short_usage
+ )
+ IF "!CONFIGSET_DIR!"=="" (
+ set ERROR_MSG="The -d option must be set for upconfig."
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -confname !CONFIGSET_NAME! -confdir !CONFIGSET_DIR! -zkHost !ZK_HOST! %ZK_VERBOSE%^
+ -configsetsDir "%SOLR_TIP%/server/solr/configsets"
+) ELSE IF "!ZK_OP!"=="downconfig" (
+ IF "!CONFIGSET_NAME!"=="" (
+ set ERROR_MSG="-n option must be set for downconfig"
+ goto zk_short_usage
+ )
+ IF "!CONFIGSET_DIR!"=="" (
+ set ERROR_MSG="The -d option must be set for downconfig."
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -confname !CONFIGSET_NAME! -confdir !CONFIGSET_DIR! -zkHost !ZK_HOST! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="cp" (
+ IF "%ZK_SRC%"=="" (
+ set ERROR_MSG=" must be specified for 'cp' command"
+ goto zk_short_usage
+ )
+ IF "%ZK_DST%"=="" (
+ set ERROR_MSG= must be specified for 'cp' command"
+ goto zk_short_usage
+ )
+ IF NOT "!ZK_SRC:~0,3!"=="zk:" (
+ IF NOT "!%ZK_DST:~0,3!"=="zk:" (
+ set ERROR_MSG="At least one of src or dst must be prefixed by 'zk:'"
+ goto zk_short_usage
+ )
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -src !ZK_SRC! -dst !ZK_DST! -recurse !ZK_RECURSE! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="mv" (
+ IF "%ZK_SRC%"=="" (
+ set ERROR_MSG=" must be specified for 'mv' command"
+ goto zk_short_usage
+ )
+ IF "%ZK_DST%"=="" (
+ set ERROR_MSG=" must be specified for 'mv' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -src !ZK_SRC! -dst !ZK_DST! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="rm" (
+ IF "%ZK_SRC"=="" (
+ set ERROR_MSG="Zookeeper path to remove must be specified when using the 'rm' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -path !ZK_SRC! -recurse !ZK_RECURSE! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="ls" (
+ IF "%ZK_SRC"=="" (
+ set ERROR_MSG="Zookeeper path to remove must be specified when using the 'ls' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -path !ZK_SRC! -recurse !ZK_RECURSE! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="mkroot" (
+ IF "%ZK_SRC"=="" (
+ set ERROR_MSG="Zookeeper path to create must be specified when using the 'mkroot' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%SOLR_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -path !ZK_SRC! %ZK_VERBOSE%
+) ELSE (
+ set ERROR_MSG="Unknown zk option !ZK_OP!"
+ goto zk_short_usage
+)
+goto done
+
+
+:run_auth
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+
+REM Options parsing.
+REM Note: With the following technique of parsing, it is not possible
+REM to have an option without a value.
+set "AUTH_PARAMS=%1"
+set "option="
+for %%a in (%*) do (
+ if not defined option (
+ set arg=%%a
+ if "!arg:~0,1!" equ "-" set "option=!arg!"
+ ) else (
+ set "option!option!=%%a"
+ if "!option!" equ "-d" set "SOLR_SERVER_DIR=%%a"
+ if "!option!" equ "-s" set "SOLR_HOME=%%a"
+ if not "!option!" equ "-s" if not "!option!" equ "-d" (
+ set "AUTH_PARAMS=!AUTH_PARAMS! !option! %%a"
+ )
+ set "option="
+ )
+)
+IF "%SOLR_SERVER_DIR%"=="" set "SOLR_SERVER_DIR=%DEFAULT_SERVER_DIR%"
+IF NOT EXIST "%SOLR_SERVER_DIR%" (
+ set "SCRIPT_ERROR=Solr server directory %SOLR_SERVER_DIR% not found!"
+ goto err
+)
+IF "%SOLR_HOME%"=="" set "SOLR_HOME=%SOLR_SERVER_DIR%\solr"
+IF EXIST "%cd%\%SOLR_HOME%" set "SOLR_HOME=%cd%\%SOLR_HOME%"
+IF NOT EXIST "%SOLR_HOME%\" (
+ IF EXIST "%SOLR_SERVER_DIR%\%SOLR_HOME%" (
+ set "SOLR_HOME=%SOLR_SERVER_DIR%\%SOLR_HOME%"
+ ) ELSE (
+ set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% not found!"
+ goto err
+ )
+)
+
+if "!AUTH_PORT!"=="" (
+ for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" set AUTH_PORT=!SOME_SOLR_PORT!
+ )
+ )
+ )
+)
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI auth %AUTH_PARAMS% -solrIncludeFile "%SOLR_INCLUDE%" -authConfDir "%SOLR_HOME%" ^
+ -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!AUTH_PORT!/solr
+goto done
+
+
+:invalid_cmd_line
+@echo.
+IF "!SCRIPT_ERROR!"=="" (
+ @echo Invalid command-line option: %1
+) ELSE (
+ @echo ERROR: !SCRIPT_ERROR!
+)
+@echo.
+IF "%FIRST_ARG%"=="start" (
+ goto start_usage
+) ELSE IF "%FIRST_ARG:~0,1%" == "-" (
+ goto start_usage
+) ELSE IF "%FIRST_ARG%"=="restart" (
+ goto start_usage
+) ELSE IF "%FIRST_ARG%"=="stop" (
+ goto stop_usage
+) ELSE IF "%FIRST_ARG%"=="healthcheck" (
+ goto healthcheck_usage
+) ELSE IF "%FIRST_ARG%"=="create" (
+ goto create_usage
+) ELSE IF "%FIRST_ARG%"=="create_core" (
+ goto create_core_usage
+) ELSE IF "%FIRST_ARG%"=="create_collection" (
+ goto create_collection_usage
+) ELSE IF "%FIRST_ARG%"=="zk" (
+ goto zk_short_usage
+) ELSE IF "%FIRST_ARG%"=="auth" (
+ goto auth_usage
+) ELSE IF "%FIRST_ARG%"=="status" (
+ goto status_usage
+) ELSE (
+ goto script_usage
+)
+
+:need_java_home
+@echo Please set the JAVA_HOME environment variable to the path where you installed Java 1.8+
+goto done
+
+:need_java_vers
+@echo Java 1.8 or later is required to run Solr.
+goto done
+
+:err
+@echo.
+@echo ERROR: !SCRIPT_ERROR!
+@echo.
+exit /b 1
+
+:done
+ENDLOCAL
+exit /b 0
+
+REM Tests what Java we have and sets some global variables
+:resolve_java_info
+
+CALL :resolve_java_vendor
+
+set JAVA_MAJOR_VERSION=0
+set JAVA_VERSION_INFO=
+set JAVA_BUILD=0
+
+FOR /f "usebackq tokens=3" %%a IN (`^""%JAVA%" -version 2^>^&1 ^| findstr "version"^"`) do (
+ set JAVA_VERSION_INFO=%%a
+ REM Remove surrounding quotes
+ set JAVA_VERSION_INFO=!JAVA_VERSION_INFO:"=!
+
+ REM Extract the major Java version, e.g. 7, 8, 9, 10 ...
+ for /f "tokens=1,2 delims=._-" %%a in ("!JAVA_VERSION_INFO!") do (
+ if %%a GEQ 9 (
+ set JAVA_MAJOR_VERSION=%%a
+ ) else (
+ set JAVA_MAJOR_VERSION=%%b
+ )
+ )
+
+ REM Don't look for "_{build}" if we're on IBM J9.
+ if NOT "%JAVA_VENDOR%" == "IBM J9" (
+ for /f "delims=_ tokens=2" %%a in ("!JAVA_VERSION_INFO!") do (
+ set /a JAVA_BUILD=%%a
+ )
+ )
+)
+GOTO :eof
+
+REM Set which JVM vendor we have
+:resolve_java_vendor
+"%JAVA%" -version 2>&1 | findstr /i "IBM J9" > nul
+if %ERRORLEVEL% == 1 ( set "JAVA_VENDOR=Oracle" ) else ( set "JAVA_VENDOR=IBM J9" )
+
+set JAVA_VENDOR_OUT=
+GOTO :eof
+
+REM Safe echo which does not mess with () in strings
+:safe_echo
+set "eout=%1"
+set eout=%eout:"=%
+echo !eout!
+GOTO :eof
diff --git a/KeywordSearch/solr/bin/autopsy-solr.in.cmd b/KeywordSearch/solr/bin/autopsy-solr.in.cmd
new file mode 100755
index 0000000000..295059b83a
--- /dev/null
+++ b/KeywordSearch/solr/bin/autopsy-solr.in.cmd
@@ -0,0 +1,173 @@
+@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one or more
+@REM contributor license agreements. See the NOTICE file distributed with
+@REM this work for additional information regarding copyright ownership.
+@REM The ASF licenses this file to You under the Apache License, Version 2.0
+@REM (the "License"); you may not use this file except in compliance with
+@REM the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing, software
+@REM distributed under the License is distributed on an "AS IS" BASIS,
+@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@REM See the License for the specific language governing permissions and
+@REM limitations under the License.
+
+@REM @echo off
+
+REM Settings here will override settings in existing env vars or in bin/solr. The default shipped state
+REM of this file is completely commented.
+
+REM By default the script will use JAVA_HOME to determine which java
+REM to use, but you can set a specific path for Solr to use without
+REM affecting other Java applications on your server/workstation.
+REM set SOLR_JAVA_HOME=
+
+REM Increase Java Min/Max Heap as needed to support your indexing / query needs
+REM set SOLR_JAVA_MEM=-Xms512m -Xmx512m
+
+REM Configure verbose GC logging:
+REM For Java 8: if this is set, additional params will be added to specify the log file & rotation
+REM For Java 9 or higher: GC_LOG_OPTS is currently not supported. If you set it, the startup script will exit with failure.
+REM set GC_LOG_OPTS=-verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime
+
+REM Various GC settings have shown to work well for a number of common Solr workloads.
+REM See solr.cmd GC_TUNE for the default list.
+REM set GC_TUNE=-XX:SurvivorRatio=4
+REM set GC_TUNE=%GC_TUNE% -XX:TargetSurvivorRatio=90
+REM set GC_TUNE=%GC_TUNE% -XX:MaxTenuringThreshold=8
+REM set GC_TUNE=%GC_TUNE% -XX:+UseConcMarkSweepGC
+REM set GC_TUNE=%GC_TUNE% -XX:ConcGCThreads=4
+REM set GC_TUNE=%GC_TUNE% -XX:ParallelGCThreads=4
+REM set GC_TUNE=%GC_TUNE% -XX:+CMSScavengeBeforeRemark
+REM set GC_TUNE=%GC_TUNE% -XX:PretenureSizeThreshold=64m
+REM set GC_TUNE=%GC_TUNE% -XX:+UseCMSInitiatingOccupancyOnly
+REM set GC_TUNE=%GC_TUNE% -XX:CMSInitiatingOccupancyFraction=50
+REM set GC_TUNE=%GC_TUNE% -XX:CMSMaxAbortablePrecleanTime=6000
+REM set GC_TUNE=%GC_TUNE% -XX:+CMSParallelRemarkEnabled
+REM set GC_TUNE=%GC_TUNE% -XX:+ParallelRefProcEnabled
+REM set GC_TUNE=%GC_TUNE% -XX:-OmitStackTraceInFastThrow etc.
+
+REM Set the ZooKeeper connection string if using an external ZooKeeper ensemble
+REM e.g. host1:2181,host2:2181/chroot
+REM Leave empty if not using SolrCloud
+REM set ZK_HOST=
+
+REM Set the ZooKeeper client timeout (for SolrCloud mode)
+REM set ZK_CLIENT_TIMEOUT=15000
+
+REM By default the start script uses "localhost"; override the hostname here
+REM for production SolrCloud environments to control the hostname exposed to cluster state
+REM set SOLR_HOST=192.168.1.1
+
+REM By default Solr will try to connect to Zookeeper with 30 seconds in timeout; override the timeout if needed
+REM set SOLR_WAIT_FOR_ZK=30
+
+REM By default the start script uses UTC; override the timezone if needed
+REM set SOLR_TIMEZONE=UTC
+
+REM Set to true to activate the JMX RMI connector to allow remote JMX client applications
+REM to monitor the JVM hosting Solr; set to "false" to disable that behavior
+REM (false is recommended in production environments)
+REM set ENABLE_REMOTE_JMX_OPTS=false
+
+REM The script will use SOLR_PORT+10000 for the RMI_PORT or you can set it here
+REM set RMI_PORT=18983
+
+REM Anything you add to the SOLR_OPTS variable will be included in the java
+REM start command line as-is, in ADDITION to other options. If you specify the
+REM -a option on start script, those options will be appended as well. Examples:
+set SOLR_OPTS=%SOLR_OPTS% -Dbootstrap_confdir=../solr/configsets/AutopsyConfig/conf -Dcollection.configName=AutopsyConfig -Dsolr.default.confdir=../solr/configsets/AutopsyConfig/conf
+
+REM Path to a directory for Solr to store cores and their data. By default, Solr will use server\solr
+REM If solr.xml is not stored in ZooKeeper, this directory needs to contain solr.xml
+REM set SOLR_HOME=
+
+REM Path to a directory that Solr will use as root for data folders for each core.
+REM If not set, defaults to /data. Overridable per core through 'dataDir' core property
+REM set SOLR_DATA_HOME=
+
+REM Changes the logging level. Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. Default is INFO
+REM This is an alternative to changing the rootLogger in log4j2.xml
+REM set SOLR_LOG_LEVEL=INFO
+
+REM Location where Solr should write logs to. Absolute or relative to solr start dir
+REM set SOLR_LOGS_DIR=logs
+
+REM Enables log rotation before starting Solr. Setting SOLR_LOG_PRESTART_ROTATION=true will let Solr take care of pre
+REM start rotation of logs. This is false by default as log4j2 handles this for us. If you choose to use another log
+REM framework that cannot do startup rotation, you may want to enable this to let Solr rotate logs on startup.
+REM set SOLR_LOG_PRESTART_ROTATION=false
+
+REM Set the host interface to listen on. Jetty will listen on all interfaces (0.0.0.0) by default.
+REM This must be an IPv4 ("a.b.c.d") or bracketed IPv6 ("[x::y]") address, not a hostname!
+REM set SOLR_JETTY_HOST=0.0.0.0
+
+REM Sets the port Solr binds to, default is 8983
+REM set SOLR_PORT=8983
+
+REM Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
+REM to enable https module with custom jetty configuration.
+REM set SOLR_SSL_ENABLED=true
+REM Uncomment to set SSL-related system properties
+REM Be sure to update the paths to the correct keystore for your environment
+REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
+REM set SOLR_SSL_KEY_STORE_PASSWORD=secret
+REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks
+REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret
+REM Require clients to authenticate
+REM set SOLR_SSL_NEED_CLIENT_AUTH=false
+REM Enable clients to authenticate (but not require)
+REM set SOLR_SSL_WANT_CLIENT_AUTH=false
+REM SSL Certificates contain host/ip "peer name" information that is validated by default. Setting
+REM this to false can be useful to disable these checks when re-using a certificate on many hosts
+REM set SOLR_SSL_CHECK_PEER_NAME=true
+REM Override Key/Trust Store types if necessary
+REM set SOLR_SSL_KEY_STORE_TYPE=JKS
+REM set SOLR_SSL_TRUST_STORE_TYPE=JKS
+
+REM Uncomment if you want to override previously defined SSL values for HTTP client
+REM otherwise keep them commented and the above values will automatically be set for HTTP clients
+REM set SOLR_SSL_CLIENT_KEY_STORE=
+REM set SOLR_SSL_CLIENT_KEY_STORE_PASSWORD=
+REM set SOLR_SSL_CLIENT_TRUST_STORE=
+REM set SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD=
+REM set SOLR_SSL_CLIENT_KEY_STORE_TYPE=
+REM set SOLR_SSL_CLIENT_TRUST_STORE_TYPE=
+
+REM Sets path of Hadoop credential provider (hadoop.security.credential.provider.path property) and
+REM enables usage of credential store.
+REM Credential provider should store the following keys:
+REM * solr.jetty.keystore.password
+REM * solr.jetty.truststore.password
+REM Set the two below if you want to set specific store passwords for HTTP client
+REM * javax.net.ssl.keyStorePassword
+REM * javax.net.ssl.trustStorePassword
+REM More info: https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/CredentialProviderAPI.html
+REM set SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks
+REM set SOLR_OPTS=" -Dsolr.ssl.credential.provider.chain=hadoop"
+
+REM Settings for authentication
+REM Please configure only one of SOLR_AUTHENTICATION_CLIENT_BUILDER or SOLR_AUTH_TYPE parameters
+REM set SOLR_AUTHENTICATION_CLIENT_BUILDER=org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory
+REM set SOLR_AUTH_TYPE=basic
+REM set SOLR_AUTHENTICATION_OPTS="-Dbasicauth=solr:SolrRocks"
+
+REM Settings for ZK ACL
+REM set SOLR_ZK_CREDS_AND_ACLS=-DzkACLProvider=org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider ^
+REM -DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider ^
+REM -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD ^
+REM -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD
+REM set SOLR_OPTS=%SOLR_OPTS% %SOLR_ZK_CREDS_AND_ACLS%
+
+REM When running Solr in non-cloud mode and if planning to do distributed search (using the "shards" parameter), the
+REM list of hosts needs to be whitelisted or Solr will forbid the request. The whitelist can be configured in solr.xml,
+REM or if you are using the OOTB solr.xml, can be specified using the system property "solr.shardsWhitelist". Alternatively
+REM host checking can be disabled by using the system property "solr.disable.shardsWhitelist"
+REM set SOLR_OPTS="%SOLR_OPTS% -Dsolr.shardsWhitelist=http://localhost:8983,http://localhost:8984"
+
+REM For a visual indication in the Admin UI of what type of environment this cluster is, configure
+REM a -Dsolr.environment property below. Valid values are prod, stage, test, dev, with an optional
+REM label or color, e.g. -Dsolr.environment=test,label=Functional+test,color=brown
+REM SOLR_OPTS="$SOLR_OPTS -Dsolr.environment=prod"
diff --git a/KeywordSearch/solr/bin/init.d/solr b/KeywordSearch/solr/bin/init.d/solr
new file mode 100755
index 0000000000..e73e0d6830
--- /dev/null
+++ b/KeywordSearch/solr/bin/init.d/solr
@@ -0,0 +1,78 @@
+#!/bin/sh
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+### BEGIN INIT INFO
+# Provides: solr
+# Required-Start: $remote_fs $syslog
+# Required-Stop: $remote_fs $syslog
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Description: Controls Apache Solr as a Service
+### END INIT INFO
+
+# Example of a very simple *nix init script that delegates commands to the bin/solr script
+# Typical usage is to do:
+#
+# cp bin/init.d/solr /etc/init.d/solr
+# chmod 755 /etc/init.d/solr
+# chown root:root /etc/init.d/solr
+# update-rc.d solr defaults
+# update-rc.d solr enable
+
+# Where you extracted the Solr distribution bundle
+SOLR_INSTALL_DIR="/opt/solr"
+
+if [ ! -d "$SOLR_INSTALL_DIR" ]; then
+ echo "$SOLR_INSTALL_DIR not found! Please check the SOLR_INSTALL_DIR setting in your $0 script."
+ exit 1
+fi
+
+# Path to an include file that defines environment specific settings to override default
+# variables used by the bin/solr script. It's highly recommended to define this script so
+# that you can keep the Solr binary files separated from live files (pid, logs, index data, etc)
+# see bin/solr.in.sh for an example
+SOLR_ENV="/etc/default/solr.in.sh"
+
+if [ ! -f "$SOLR_ENV" ]; then
+ echo "$SOLR_ENV not found! Please check the SOLR_ENV setting in your $0 script."
+ exit 1
+fi
+
+# Specify the user to run Solr as; if not set, then Solr will run as root.
+# Running Solr as root is not recommended for production environments
+RUNAS="solr"
+
+# verify the specified run as user exists
+runas_uid="`id -u "$RUNAS"`"
+if [ $? -ne 0 ]; then
+ echo "User $RUNAS not found! Please create the $RUNAS user before running this script."
+ exit 1
+fi
+
+case "$1" in
+ start|stop|restart|status)
+ SOLR_CMD="$1"
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|status}"
+ exit
+esac
+
+if [ -n "$RUNAS" ]; then
+ su -c "SOLR_INCLUDE=\"$SOLR_ENV\" \"$SOLR_INSTALL_DIR/bin/solr\" $SOLR_CMD" - "$RUNAS"
+else
+ SOLR_INCLUDE="$SOLR_ENV" "$SOLR_INSTALL_DIR/bin/solr" "$SOLR_CMD"
+fi
diff --git a/KeywordSearch/solr/bin/install_solr_service.sh b/KeywordSearch/solr/bin/install_solr_service.sh
new file mode 100755
index 0000000000..6cfb6a578e
--- /dev/null
+++ b/KeywordSearch/solr/bin/install_solr_service.sh
@@ -0,0 +1,370 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [[ $EUID -ne 0 ]]; then
+ echo -e "\nERROR: This script must be run as root\n" 1>&2
+ exit 1
+fi
+
+print_usage() {
+ ERROR_MSG="$1"
+
+ if [ "$ERROR_MSG" != "" ]; then
+ echo -e "\nERROR: $ERROR_MSG\n" 1>&2
+ fi
+
+ echo ""
+ echo "Usage: install_solr_service.sh [OPTIONS]"
+ echo ""
+ echo " The first argument to the script must be a path to a Solr distribution archive, such as solr-5.0.0.tgz"
+ echo " (only .tgz or .zip are supported formats for the archive)"
+ echo ""
+ echo " Supported OPTIONS include:"
+ echo ""
+ echo " -d Directory for live / writable Solr files, such as logs, pid files, and index data; defaults to /var/solr"
+ echo ""
+ echo " -i Directory to extract the Solr installation archive; defaults to /opt/"
+ echo " The specified path must exist prior to using this script."
+ echo ""
+ echo " -p Port Solr should bind to; default is 8983"
+ echo ""
+ echo " -s Service name; defaults to solr"
+ echo ""
+ echo " -u User to own the Solr files and run the Solr process as; defaults to solr"
+ echo " This script will create the specified user account if it does not exist."
+ echo ""
+ echo " -f Upgrade Solr. Overwrite symlink and init script of previous installation."
+ echo ""
+ echo " -n Do not start Solr service after install, and do not abort on missing Java"
+ echo ""
+ echo " NOTE: Must be run as the root user"
+ echo ""
+} # end print_usage
+
+print_error() {
+ echo $1
+ exit 1
+}
+
+# Locate *NIX distribution by looking for match from various detection strategies
+# We start with /etc/os-release, as this will also work for Docker containers
+for command in "grep -E \"^NAME=\" /etc/os-release" \
+ "lsb_release -i" \
+ "cat /proc/version" \
+ "uname -a" ; do
+ distro_string=$(eval $command 2>/dev/null)
+ unset distro
+ if [[ ${distro_string,,} == *"debian"* ]]; then
+ distro=Debian
+ elif [[ ${distro_string,,} == *"red hat"* ]]; then
+ distro=RedHat
+ elif [[ ${distro_string,,} == *"centos"* ]]; then
+ distro=CentOS
+ elif [[ ${distro_string,,} == *"ubuntu"* ]]; then
+ distro=Ubuntu
+ elif [[ ${distro_string,,} == *"suse"* ]]; then
+ distro=SUSE
+ elif [[ ${distro_string,,} == *"darwin"* ]]; then
+ echo "Sorry, this script does not support macOS. You'll need to setup Solr as a service manually using the documentation provided in the Solr Reference Guide."
+ echo "You could also try installing via Homebrew (http://brew.sh/), e.g. brew install solr"
+ exit 1
+ fi
+ if [[ $distro ]] ; then break ; fi
+done
+if [[ ! $distro ]] ; then
+ echo -e "\nERROR: Unable to auto-detect your *NIX distribution!\nYou'll need to setup Solr as a service manually using the documentation provided in the Solr Reference Guide.\n" 1>&2
+ exit 1
+fi
+
+if [ -z "$1" ]; then
+ print_usage "Must specify the path to the Solr installation archive, such as solr-5.0.0.tgz"
+ exit 1
+fi
+
+SOLR_ARCHIVE=$1
+if [ ! -f "$SOLR_ARCHIVE" ]; then
+ print_usage "Specified Solr installation archive $SOLR_ARCHIVE not found!"
+ exit 1
+fi
+
+# strip off path info
+SOLR_INSTALL_FILE=${SOLR_ARCHIVE##*/}
+is_tar=true
+if [ ${SOLR_INSTALL_FILE: -4} == ".tgz" ]; then
+ SOLR_DIR=${SOLR_INSTALL_FILE%.tgz}
+elif [ ${SOLR_INSTALL_FILE: -4} == ".zip" ]; then
+ SOLR_DIR=${SOLR_INSTALL_FILE%.zip}
+ is_tar=false
+else
+ print_usage "Solr installation archive $SOLR_ARCHIVE is invalid, expected a .tgz or .zip file!"
+ exit 1
+fi
+
+SOLR_START=true
+if [ $# -gt 1 ]; then
+ shift
+ while true; do
+ case $1 in
+ -i)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "Directory path is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_EXTRACT_DIR=$2
+ shift 2
+ ;;
+ -d)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "Directory path is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_VAR_DIR="$2"
+ shift 2
+ ;;
+ -u)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "Username is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_USER="$2"
+ shift 2
+ ;;
+ -s)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "Service name is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_SERVICE="$2"
+ shift 2
+ ;;
+ -p)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "Port is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_PORT="$2"
+ shift 2
+ ;;
+ -f)
+ SOLR_UPGRADE="YES"
+ shift 1
+ ;;
+ -n)
+ SOLR_START=false
+ shift 1
+ ;;
+ -help|-usage)
+ print_usage ""
+ exit 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ if [ "$1" != "" ]; then
+ print_usage "Unrecognized or misplaced argument: $1!"
+ exit 1
+ else
+ break # out-of-args, stop looping
+ fi
+ ;;
+ esac
+ done
+fi
+
+# Test for availability of needed tools
+if [[ $is_tar ]] ; then
+ tar --version &>/dev/null || print_error "Script requires the 'tar' command"
+else
+ unzip -hh &>/dev/null || print_error "Script requires the 'unzip' command"
+fi
+if [[ $SOLR_START == "true" ]] ; then
+ service --version &>/dev/null || service --help &>/dev/null || print_error "Script requires the 'service' command"
+ java -version &>/dev/null || print_error "Solr requires java, please install or set JAVA_HOME properly"
+fi
+lsof -h &>/dev/null || echo "We recommend installing the 'lsof' command for more stable start/stop of Solr"
+
+
+if [ -z "$SOLR_EXTRACT_DIR" ]; then
+ SOLR_EXTRACT_DIR=/opt
+fi
+
+if [ ! -d "$SOLR_EXTRACT_DIR" ]; then
+ print_usage "Installation directory $SOLR_EXTRACT_DIR not found! Please create it before running this script."
+ exit 1
+fi
+
+if [ -z "$SOLR_SERVICE" ]; then
+ SOLR_SERVICE=solr
+fi
+
+if [ -z "$SOLR_VAR_DIR" ]; then
+ SOLR_VAR_DIR="/var/$SOLR_SERVICE"
+fi
+
+if [ -z "$SOLR_USER" ]; then
+ SOLR_USER=solr
+fi
+
+if [ -z "$SOLR_PORT" ]; then
+ SOLR_PORT=8983
+fi
+
+if [ -z "$SOLR_UPGRADE" ]; then
+ SOLR_UPGRADE=NO
+fi
+
+if [ ! "$SOLR_UPGRADE" = "YES" ]; then
+ if [ -f "/etc/init.d/$SOLR_SERVICE" ]; then
+ print_usage "/etc/init.d/$SOLR_SERVICE already exists! Perhaps Solr is already setup as a service on this host? To upgrade Solr use the -f option."
+ exit 1
+ fi
+
+ if [ -e "$SOLR_EXTRACT_DIR/$SOLR_SERVICE" ]; then
+ print_usage "$SOLR_EXTRACT_DIR/$SOLR_SERVICE already exists! Please move this directory / link or choose a different service name using the -s option."
+ exit 1
+ fi
+fi
+
+# stop running instance
+if [ -f "/etc/init.d/$SOLR_SERVICE" ]; then
+ echo -e "\nStopping Solr instance if exists ...\n"
+ service "$SOLR_SERVICE" stop
+fi
+
+# create user if not exists
+solr_uid="`id -u "$SOLR_USER"`"
+if [ $? -ne 0 ]; then
+ echo "Creating new user: $SOLR_USER"
+ if [ "$distro" == "RedHat" ] || [ "$distro" == "CentOS" ] ; then
+ adduser --system -U -m --home-dir "$SOLR_VAR_DIR" "$SOLR_USER"
+ elif [ "$distro" == "SUSE" ]; then
+ useradd --system -U -m --home-dir "$SOLR_VAR_DIR" "$SOLR_USER"
+ else
+ adduser --system --shell /bin/bash --group --disabled-password --home "$SOLR_VAR_DIR" "$SOLR_USER"
+ fi
+fi
+
+# extract
+SOLR_INSTALL_DIR="$SOLR_EXTRACT_DIR/$SOLR_DIR"
+if [ ! -d "$SOLR_INSTALL_DIR" ]; then
+
+ echo -e "\nExtracting $SOLR_ARCHIVE to $SOLR_EXTRACT_DIR\n"
+
+ if $is_tar ; then
+ tar zxf "$SOLR_ARCHIVE" -C "$SOLR_EXTRACT_DIR"
+ else
+ unzip -q "$SOLR_ARCHIVE" -d "$SOLR_EXTRACT_DIR"
+ fi
+
+ if [ ! -d "$SOLR_INSTALL_DIR" ]; then
+ echo -e "\nERROR: Expected directory $SOLR_INSTALL_DIR not found after extracting $SOLR_ARCHIVE ... script fails.\n" 1>&2
+ exit 1
+ fi
+
+ chown -R root: "$SOLR_INSTALL_DIR"
+ find "$SOLR_INSTALL_DIR" -type d -print0 | xargs -0 chmod 0755
+ find "$SOLR_INSTALL_DIR" -type f -print0 | xargs -0 chmod 0644
+ chmod -R 0755 "$SOLR_INSTALL_DIR/bin"
+else
+ echo -e "\nWARNING: $SOLR_INSTALL_DIR already exists! Skipping extract ...\n"
+fi
+
+# create a symlink for easier scripting
+if [ -h "$SOLR_EXTRACT_DIR/$SOLR_SERVICE" ]; then
+ echo -e "\nRemoving old symlink $SOLR_EXTRACT_DIR/$SOLR_SERVICE ...\n"
+ rm "$SOLR_EXTRACT_DIR/$SOLR_SERVICE"
+fi
+if [ -e "$SOLR_EXTRACT_DIR/$SOLR_SERVICE" ]; then
+ echo -e "\nWARNING: $SOLR_EXTRACT_DIR/$SOLR_SERVICE is not symlink! Skipping symlink update ...\n"
+else
+ echo -e "\nInstalling symlink $SOLR_EXTRACT_DIR/$SOLR_SERVICE -> $SOLR_INSTALL_DIR ...\n"
+ ln -s "$SOLR_INSTALL_DIR" "$SOLR_EXTRACT_DIR/$SOLR_SERVICE"
+fi
+
+# install init.d script
+echo -e "\nInstalling /etc/init.d/$SOLR_SERVICE script ...\n"
+cp "$SOLR_INSTALL_DIR/bin/init.d/solr" "/etc/init.d/$SOLR_SERVICE"
+chmod 0744 "/etc/init.d/$SOLR_SERVICE"
+chown root: "/etc/init.d/$SOLR_SERVICE"
+# do some basic variable substitution on the init.d script
+sed_expr1="s#SOLR_INSTALL_DIR=.*#SOLR_INSTALL_DIR=\"$SOLR_EXTRACT_DIR/$SOLR_SERVICE\"#"
+sed_expr2="s#SOLR_ENV=.*#SOLR_ENV=\"/etc/default/$SOLR_SERVICE.in.sh\"#"
+sed_expr3="s#RUNAS=.*#RUNAS=\"$SOLR_USER\"#"
+sed_expr4="s#Provides:.*#Provides: $SOLR_SERVICE#"
+sed -i -e "$sed_expr1" -e "$sed_expr2" -e "$sed_expr3" -e "$sed_expr4" "/etc/init.d/$SOLR_SERVICE"
+
+# install/move configuration
+if [ ! -d /etc/default ]; then
+ mkdir /etc/default
+ chown root: /etc/default
+ chmod 0755 /etc/default
+fi
+if [ -f "$SOLR_VAR_DIR/solr.in.sh" ]; then
+ echo -e "\nMoving existing $SOLR_VAR_DIR/solr.in.sh to /etc/default/$SOLR_SERVICE.in.sh ...\n"
+ mv "$SOLR_VAR_DIR/solr.in.sh" "/etc/default/$SOLR_SERVICE.in.sh"
+elif [ -f "/etc/default/$SOLR_SERVICE.in.sh" ]; then
+ echo -e "\n/etc/default/$SOLR_SERVICE.in.sh already exist. Skipping install ...\n"
+else
+ echo -e "\nInstalling /etc/default/$SOLR_SERVICE.in.sh ...\n"
+ cp "$SOLR_INSTALL_DIR/bin/solr.in.sh" "/etc/default/$SOLR_SERVICE.in.sh"
+ mv "$SOLR_INSTALL_DIR/bin/solr.in.sh" "$SOLR_INSTALL_DIR/bin/solr.in.sh.orig"
+ mv "$SOLR_INSTALL_DIR/bin/solr.in.cmd" "$SOLR_INSTALL_DIR/bin/solr.in.cmd.orig"
+ echo "SOLR_PID_DIR=\"$SOLR_VAR_DIR\"
+SOLR_HOME=\"$SOLR_VAR_DIR/data\"
+LOG4J_PROPS=\"$SOLR_VAR_DIR/log4j2.xml\"
+SOLR_LOGS_DIR=\"$SOLR_VAR_DIR/logs\"
+SOLR_PORT=\"$SOLR_PORT\"
+" >> "/etc/default/$SOLR_SERVICE.in.sh"
+fi
+chown root:${SOLR_USER} "/etc/default/$SOLR_SERVICE.in.sh"
+chmod 0640 "/etc/default/$SOLR_SERVICE.in.sh"
+
+# install data directories and files
+mkdir -p "$SOLR_VAR_DIR/data"
+mkdir -p "$SOLR_VAR_DIR/logs"
+if [ -f "$SOLR_VAR_DIR/data/solr.xml" ]; then
+ echo -e "\n$SOLR_VAR_DIR/data/solr.xml already exists. Skipping install ...\n"
+else
+ cp "$SOLR_INSTALL_DIR/server/solr/"{solr.xml,zoo.cfg} "$SOLR_VAR_DIR/data/"
+fi
+if [ -f "$SOLR_VAR_DIR/log4j2.xml" ]; then
+ echo -e "\n$SOLR_VAR_DIR/log4j2.xml already exists. Skipping install ...\n"
+else
+ cp "$SOLR_INSTALL_DIR/server/resources/log4j2.xml" "$SOLR_VAR_DIR/log4j2.xml"
+fi
+chown -R "$SOLR_USER:" "$SOLR_VAR_DIR"
+find "$SOLR_VAR_DIR" -type d -print0 | xargs -0 chmod 0750
+find "$SOLR_VAR_DIR" -type f -print0 | xargs -0 chmod 0640
+
+# configure autostart of service
+if [[ "$distro" == "RedHat" || "$distro" == "CentOS" || "$distro" == "SUSE" ]]; then
+ chkconfig "$SOLR_SERVICE" on
+else
+ update-rc.d "$SOLR_SERVICE" defaults
+fi
+echo "Service $SOLR_SERVICE installed."
+echo "Customize Solr startup configuration in /etc/default/$SOLR_SERVICE.in.sh"
+
+# start service
+if [[ $SOLR_START == "true" ]] ; then
+ service "$SOLR_SERVICE" start
+ sleep 5
+ service "$SOLR_SERVICE" status
+else
+ echo "Not starting Solr service (option -n given). Start manually with 'service $SOLR_SERVICE start'"
+fi
diff --git a/KeywordSearch/solr/bin/oom_solr.sh b/KeywordSearch/solr/bin/oom_solr.sh
new file mode 100755
index 0000000000..5ecba6bc30
--- /dev/null
+++ b/KeywordSearch/solr/bin/oom_solr.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+SOLR_PORT=$1
+SOLR_LOGS_DIR=$2
+SOLR_PID=`ps auxww | grep start.jar | grep $SOLR_PORT | grep -v grep | awk '{print $2}' | sort -r`
+if [ -z "$SOLR_PID" ]; then
+ echo "Couldn't find Solr process running on port $SOLR_PORT!"
+ exit
+fi
+NOW=$(date +"%F_%H_%M_%S")
+(
+echo "Running OOM killer script for process $SOLR_PID for Solr on port $SOLR_PORT"
+kill -9 $SOLR_PID
+echo "Killed process $SOLR_PID"
+) | tee $SOLR_LOGS_DIR/solr_oom_killer-$SOLR_PORT-$NOW.log
diff --git a/KeywordSearch/solr/bin/post b/KeywordSearch/solr/bin/post
new file mode 100755
index 0000000000..4c629d1059
--- /dev/null
+++ b/KeywordSearch/solr/bin/post
@@ -0,0 +1,239 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ====== Common code copied/adapted from bin/solr (TODO: centralize/share this kind of thing across bin/solr, etc)
+
+THIS_SCRIPT="$0"
+
+# Resolve symlinks to this script
+while [ -h "$THIS_SCRIPT" ] ; do
+ ls=`ls -ld "$THIS_SCRIPT"`
+ # Drop everything prior to ->
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ THIS_SCRIPT="$link"
+ else
+ THIS_SCRIPT=`dirname "$THIS_SCRIPT"`/"$link"
+ fi
+done
+
+SOLR_TIP=`dirname "$THIS_SCRIPT"`/..
+SOLR_TIP=`cd "$SOLR_TIP"; pwd`
+
+if [ -n "$SOLR_JAVA_HOME" ]; then
+ JAVA="$SOLR_JAVA_HOME/bin/java"
+elif [ -n "$JAVA_HOME" ]; then
+ for java in "$JAVA_HOME"/bin/amd64/java "$JAVA_HOME"/bin/java; do
+ if [ -x "$java" ]; then
+ JAVA="$java"
+ break
+ fi
+ done
+else
+ JAVA=java
+fi
+
+# test that Java exists and is executable on this server
+"$JAVA" -version >/dev/null 2>&1 || { echo >&2 "Java is required to run this tool! Please install Java 8 or greater before running this script."; exit 1; }
+
+
+# ===== post specific code
+
+TOOL_JAR=("$SOLR_TIP/dist"/solr-core-*.jar)
+
+function print_usage() {
+ echo ""
+ echo 'Usage: post -c [OPTIONS] '
+ echo " or post -help"
+ echo ""
+ echo " collection name defaults to DEFAULT_SOLR_COLLECTION if not specified"
+ echo ""
+ echo "OPTIONS"
+ echo "======="
+ echo " Solr options:"
+ echo " -url (overrides collection, host, and port)"
+ echo " -host (default: localhost)"
+ echo " -p or -port (default: 8983)"
+ echo " -commit yes|no (default: yes)"
+ echo " -u or -user (sets BasicAuth credentials)"
+ # optimize intentionally omitted, but can be used as '-optimize yes' (default: no)
+ echo ""
+ echo " Web crawl options:"
+ echo " -recursive (default: 1)"
+ echo " -delay (default: 10)"
+ echo ""
+ echo " Directory crawl options:"
+ echo " -delay (default: 0)"
+ echo ""
+ echo " stdin/args options:"
+ echo " -type (default: application/xml)"
+ echo ""
+ echo " Other options:"
+ echo " -filetypes [,,...] (default: xml,json,jsonl,csv,pdf,doc,docx,ppt,pptx,xls,xlsx,odt,odp,ods,ott,otp,ots,rtf,htm,html,txt,log)"
+ echo " -params \"=[&=...]\" (values must be URL-encoded; these pass through to Solr update request)"
+ echo " -out yes|no (default: no; yes outputs Solr response to console)"
+ echo " -format solr (sends application/json content as Solr commands to /update instead of /update/json/docs)"
+ echo ""
+ echo ""
+ echo "Examples:"
+ echo ""
+ echo "* JSON file: $THIS_SCRIPT -c wizbang events.json"
+ echo "* XML files: $THIS_SCRIPT -c records article*.xml"
+ echo "* CSV file: $THIS_SCRIPT -c signals LATEST-signals.csv"
+ echo "* Directory of files: $THIS_SCRIPT -c myfiles ~/Documents"
+ echo "* Web crawl: $THIS_SCRIPT -c gettingstarted http://lucene.apache.org/solr -recursive 1 -delay 1"
+ echo "* Standard input (stdin): echo '{"commit": {}}' | $THIS_SCRIPT -c my_collection -type application/json -out yes -d"
+ echo "* Data as string: $THIS_SCRIPT -c signals -type text/csv -out yes -d $'id,value\n1,0.47'"
+ echo ""
+} # end print_usage
+
+if [[ $# -eq 1 && ("$1" == "-help" || "$1" == "-h" || "$1" == "-usage") ]]; then
+ print_usage
+ exit
+fi
+
+
+COLLECTION="$DEFAULT_SOLR_COLLECTION"
+PROPS=('-Dauto=yes')
+RECURSIVE=""
+FILES=()
+URLS=()
+ARGS=()
+
+while [ $# -gt 0 ]; do
+ # TODO: natively handle the optional parameters to SPT
+ # but for now they can be specified as bin/post -c collection-name delay=5 http://lucidworks.com
+
+ if [[ -d "$1" ]]; then
+ # Directory
+# echo "$1: DIRECTORY"
+ RECURSIVE=yes
+ FILES+=("$1")
+ elif [[ -f "$1" ]]; then
+ # File
+# echo "$1: FILE"
+ FILES+=("$1")
+ elif [[ "$1" == http* ]]; then
+ # URL
+# echo "$1: URL"
+ URLS+=("$1")
+ else
+ if [[ "$1" == -* ]]; then
+ if [[ "$1" == "-c" ]]; then
+ # Special case, pull out collection name
+ shift
+ COLLECTION="$1"
+ elif [[ "$1" == "-p" ]]; then
+ # -p alias for -port for convenience and compatibility with `bin/solr start`
+ shift
+ PROPS+=("-Dport=$1")
+ elif [[ ("$1" == "-d" || "$1" == "--data" || "$1" == "-") ]]; then
+ if [[ ! -t 0 ]]; then
+ MODE="stdin"
+ else
+ # when no stdin exists and -d specified, the rest of the arguments
+ # are assumed to be strings to post as-is
+ MODE="args"
+ shift
+ if [[ $# -gt 0 ]]; then
+ ARGS=("$@")
+ shift $#
+ else
+ # SPT needs a valid args string, useful for 'bin/post -c foo -d' to force a commit
+ ARGS+=("")
+ fi
+ fi
+ elif [[ ("$1" == "-u" || "$1" == "-user") ]]; then
+ shift
+ PROPS+=("-Dbasicauth=$1")
+ else
+ if [[ "$1" == -D* ]] ; then
+ PROPS+=("$1")
+ if [[ "${1:2:4}" == "url=" ]]; then
+ SOLR_URL=${1:6}
+ fi
+ else
+ key="${1:1}"
+ shift
+ # echo "$1: PROP"
+ PROPS+=("-D$key=$1")
+ if [[ "$key" == "url" ]]; then
+ SOLR_URL=$1
+ fi
+ fi
+ fi
+ else
+ echo -e "\nUnrecognized argument: $1\n"
+ echo -e "If this was intended to be a data file, it does not exist relative to $PWD\n"
+ exit 1
+ fi
+ fi
+ shift
+done
+
+# Check for errors
+if [[ $COLLECTION == "" && $SOLR_URL == "" ]]; then
+ echo -e "\nCollection or URL must be specified. Use -c or set DEFAULT_SOLR_COLLECTION in your environment, or use -url instead.\n"
+ echo -e "See '$THIS_SCRIPT -h' for usage instructions.\n"
+ exit 1
+fi
+
+# Unsupported: bin/post -c foo
+if [[ ${#FILES[@]} == 0 && ${#URLS[@]} == 0 && $MODE != "stdin" && $MODE != "args" ]]; then
+ echo -e "\nNo files, directories, URLs, -d strings, or stdin were specified.\n"
+ echo -e "See '$THIS_SCRIPT -h' for usage instructions.\n"
+ exit 1
+fi
+
+# SPT does not support mixing different data mode types, just files, just URLs, just stdin, or just argument strings.
+# The following are unsupported constructs:
+# bin/post -c foo existing_file.csv http://example.com
+# echo '' | bin/post -c foo existing_file.csv
+# bin/post -c foo existing_file.csv -d 'anything'
+if [[ (${#FILES[@]} != 0 && ${#URLS[@]} != 0 && $MODE != "stdin" && $MODE != "args")
+ || ((${#FILES[@]} != 0 || ${#URLS[@]} != 0) && ($MODE == "stdin" || $MODE == "args")) ]]; then
+ echo -e "\nCombining files/directories, URLs, stdin, or args is not supported. Post them separately.\n"
+ exit 1
+fi
+
+PARAMS=""
+
+# TODO: let's simplify this
+if [[ $MODE != "stdin" && $MODE != "args" ]]; then
+ if [[ $FILES != "" ]]; then
+ MODE="files"
+ PARAMS=("${FILES[@]}")
+ fi
+
+ if [[ $URLS != "" ]]; then
+ MODE="web"
+ PARAMS=("${URLS[@]}")
+ fi
+else
+ PARAMS=("${ARGS[@]}")
+fi
+
+PROPS+=("-Dc=$COLLECTION" "-Ddata=$MODE")
+if [[ -n "$RECURSIVE" ]]; then
+ PROPS+=('-Drecursive=yes')
+fi
+
+echo "$JAVA" -classpath "${TOOL_JAR[0]}" "${PROPS[@]}" org.apache.solr.util.SimplePostTool "${PARAMS[@]}"
+"$JAVA" -classpath "${TOOL_JAR[0]}" "${PROPS[@]}" org.apache.solr.util.SimplePostTool "${PARAMS[@]}"
+
+# post smoker:
+# bin/post -c signals -out yes -type application/json -d '[{"id": 2, "val": 0.47}]'
+# bin/post -c signals -out yes -params "wt=json" -d '1'
diff --git a/KeywordSearch/solr/bin/solr b/KeywordSearch/solr/bin/solr
new file mode 100755
index 0000000000..81e98a5269
--- /dev/null
+++ b/KeywordSearch/solr/bin/solr
@@ -0,0 +1,2175 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# CONTROLLING STARTUP:
+#
+# Use solr -help to see available command-line options. In addition
+# to passing command-line options, this script looks for an include
+# file named solr.in.sh to set environment variables. Specifically,
+# the following locations are searched in this order:
+#
+# ./
+# $HOME/.solr.in.sh
+# /usr/share/solr
+# /usr/local/share/solr
+# /var/solr/
+# /opt/solr
+#
+# Another option is to specify the full path to the include file in the
+# environment. For example:
+#
+# $ SOLR_INCLUDE=/path/to/solr.in.sh solr start
+#
+# Note: This is particularly handy for running multiple instances on a
+# single installation, or for quick tests.
+#
+# Finally, developers and enthusiasts who frequently run from an SVN
+# checkout, and do not want to locally modify bin/solr.in.sh, can put
+# a customized include file at ~/.solr.in.sh.
+#
+# If you would rather configure startup entirely from the environment, you
+# can disable the include by exporting an empty SOLR_INCLUDE, or by
+# ensuring that no include files exist in the aforementioned search list.
+
+SOLR_SCRIPT="$0"
+verbose=false
+THIS_OS=`uname -s`
+
+# What version of Java is required to run this version of Solr.
+JAVA_VER_REQ="8"
+
+stop_all=false
+
+# for now, we don't support running this script from cygwin due to problems
+# like not having lsof, ps auxww, curl, and awkward directory handling
+if [ "${THIS_OS:0:6}" == "CYGWIN" ]; then
+ echo -e "This script does not support cygwin due to severe limitations and lack of adherence\nto BASH standards, such as lack of lsof, curl, and ps options.\n\nPlease use the native solr.cmd script on Windows!"
+ exit 1
+fi
+
+# Resolve symlinks to this script
+while [ -h "$SOLR_SCRIPT" ] ; do
+ ls=`ls -ld "$SOLR_SCRIPT"`
+ # Drop everything prior to ->
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ SOLR_SCRIPT="$link"
+ else
+ SOLR_SCRIPT=`dirname "$SOLR_SCRIPT"`/"$link"
+ fi
+done
+
+SOLR_TIP=`dirname "$SOLR_SCRIPT"`/..
+SOLR_TIP=`cd "$SOLR_TIP"; pwd`
+DEFAULT_SERVER_DIR="$SOLR_TIP/server"
+
+# If an include wasn't specified in the environment, then search for one...
+if [ -z "$SOLR_INCLUDE" ]; then
+ # Locations (in order) to use when searching for an include file.
+ for include in "`dirname "$0"`/solr.in.sh" \
+ "$HOME/.solr.in.sh" \
+ /usr/share/solr/solr.in.sh \
+ /usr/local/share/solr/solr.in.sh \
+ /etc/default/solr.in.sh \
+ /opt/solr/solr.in.sh; do
+ if [ -r "$include" ]; then
+ SOLR_INCLUDE="$include"
+ . "$include"
+ break
+ fi
+ done
+elif [ -r "$SOLR_INCLUDE" ]; then
+ . "$SOLR_INCLUDE"
+fi
+
+if [ -z "$SOLR_PID_DIR" ]; then
+ SOLR_PID_DIR="$SOLR_TIP/bin"
+fi
+
+if [ -n "$SOLR_JAVA_HOME" ]; then
+ JAVA="$SOLR_JAVA_HOME/bin/java"
+elif [ -n "$JAVA_HOME" ]; then
+ for java in "$JAVA_HOME"/bin/amd64/java "$JAVA_HOME"/bin/java; do
+ if [ -x "$java" ]; then
+ JAVA="$java"
+ break
+ fi
+ done
+ if [ -z "$JAVA" ]; then
+ echo >&2 "The currently defined JAVA_HOME ($JAVA_HOME) refers"
+ echo >&2 "to a location where Java could not be found. Aborting."
+ echo >&2 "Either fix the JAVA_HOME variable or remove it from the"
+ echo >&2 "environment so that the system PATH will be searched."
+ exit 1
+ fi
+else
+ JAVA=java
+fi
+
+if [ -z "$SOLR_STOP_WAIT" ]; then
+ SOLR_STOP_WAIT=180
+fi
+# test that Java exists, is executable and correct version
+JAVA_VER=$("$JAVA" -version 2>&1)
+if [[ $? -ne 0 ]] ; then
+ echo >&2 "Java not found, or an error was encountered when running java."
+ echo >&2 "A working Java $JAVA_VER_REQ JRE is required to run Solr!"
+ echo >&2 "Please install latest version of Java $JAVA_VER_REQ or set JAVA_HOME properly."
+ echo >&2 "Command that we tried: '${JAVA} -version', with response:"
+ echo >&2 "${JAVA_VER}"
+ echo >&2
+ echo >&2 "Debug information:"
+ echo >&2 "JAVA_HOME: ${JAVA_HOME:-N/A}"
+ echo >&2 "Active Path:"
+ echo >&2 "${PATH}"
+ exit 1
+else
+ JAVA_VER_NUM=$(echo $JAVA_VER | head -1 | awk -F '"' '/version/ {print $2}' | sed -e's/^1\.//' | sed -e's/[._-].*$//')
+ if [[ "$JAVA_VER_NUM" -lt "$JAVA_VER_REQ" ]] ; then
+ echo >&2 "Your current version of Java is too old to run this version of Solr."
+ echo >&2 "We found major version $JAVA_VER_NUM, using command '${JAVA} -version', with response:"
+ echo >&2 "${JAVA_VER}"
+ echo >&2
+ echo >&2 "Please install latest version of Java $JAVA_VER_REQ or set JAVA_HOME properly."
+ echo >&2
+ echo >&2 "Debug information:"
+ echo >&2 "JAVA_HOME: ${JAVA_HOME:-N/A}"
+ echo >&2 "Active Path:"
+ echo >&2 "${PATH}"
+ exit 1
+ fi
+ JAVA_VENDOR="Oracle"
+ if [ "`echo $JAVA_VER | grep -i "IBM J9"`" != "" ]; then
+ JAVA_VENDOR="IBM J9"
+ fi
+fi
+
+
+# Select HTTP OR HTTPS related configurations
+SOLR_URL_SCHEME=http
+SOLR_JETTY_CONFIG=()
+SOLR_SSL_OPTS=""
+
+if [ -n "$SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH" ]; then
+ SOLR_SSL_OPTS+=" -Dhadoop.security.credential.provider.path=$SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH"
+fi
+
+if [ -z "$SOLR_SSL_ENABLED" ]; then
+ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
+ SOLR_SSL_ENABLED="true" # implicitly from earlier behaviour
+ else
+ SOLR_SSL_ENABLED="false"
+ fi
+fi
+if [ "$SOLR_SSL_ENABLED" == "true" ]; then
+ if [[ "$JAVA_VER_NUM" -lt "9" ]] ; then
+ echo >&2 "HTTP/2 + SSL is not support in Java 8. "
+ echo >&2 "Configure Solr with HTTP/1.1 + SSL"
+ SOLR_JETTY_CONFIG+=("--module=https8")
+ else
+ SOLR_JETTY_CONFIG+=("--module=https")
+ fi
+
+ SOLR_JETTY_CONFIG+=("--lib=$DEFAULT_SERVER_DIR/solr-webapp/webapp/WEB-INF/lib/*")
+ SOLR_URL_SCHEME=https
+ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
+ SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE"
+ fi
+ if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then
+ export SOLR_SSL_KEY_STORE_PASSWORD=$SOLR_SSL_KEY_STORE_PASSWORD
+ fi
+ if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then
+ SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.type=$SOLR_SSL_KEY_STORE_TYPE"
+ fi
+
+ if [ -n "$SOLR_SSL_TRUST_STORE" ]; then
+ SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore=$SOLR_SSL_TRUST_STORE"
+ fi
+ if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then
+ export SOLR_SSL_TRUST_STORE_PASSWORD=$SOLR_SSL_TRUST_STORE_PASSWORD
+ fi
+ if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then
+ SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.type=$SOLR_SSL_TRUST_STORE_TYPE"
+ fi
+
+ if [ -n "$SOLR_SSL_NEED_CLIENT_AUTH" ]; then
+ SOLR_SSL_OPTS+=" -Dsolr.jetty.ssl.needClientAuth=$SOLR_SSL_NEED_CLIENT_AUTH"
+ fi
+ if [ -n "$SOLR_SSL_WANT_CLIENT_AUTH" ]; then
+ SOLR_SSL_OPTS+=" -Dsolr.jetty.ssl.wantClientAuth=$SOLR_SSL_WANT_CLIENT_AUTH"
+ fi
+
+ if [ -n "$SOLR_SSL_CLIENT_KEY_STORE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_CLIENT_KEY_STORE"
+
+ if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD" ]; then
+ export SOLR_SSL_CLIENT_KEY_STORE_PASSWORD=$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD
+ fi
+ if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_TYPE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_CLIENT_KEY_STORE_TYPE"
+ fi
+ else
+ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_KEY_STORE"
+ fi
+ if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_KEY_STORE_TYPE"
+ fi
+ fi
+
+ if [ -n "$SOLR_SSL_CHECK_PEER_NAME" ]; then
+ SOLR_SSL_OPTS+=" -Dsolr.ssl.checkPeerName=$SOLR_SSL_CHECK_PEER_NAME"
+ fi
+
+ if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_CLIENT_TRUST_STORE"
+
+ if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD" ]; then
+ export SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD=$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD
+ fi
+ if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_TYPE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_CLIENT_TRUST_STORE_TYPE"
+ fi
+ else
+ if [ -n "$SOLR_SSL_TRUST_STORE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_TRUST_STORE"
+ fi
+
+ if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then
+ SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_TRUST_STORE_TYPE"
+ fi
+ fi
+else
+ SOLR_JETTY_CONFIG+=("--module=http")
+fi
+
+# Authentication options
+if [ -z "$SOLR_AUTH_TYPE" ] && [ -n "$SOLR_AUTHENTICATION_OPTS" ]; then
+ echo "WARNING: SOLR_AUTHENTICATION_OPTS environment variable configured without associated SOLR_AUTH_TYPE variable"
+ echo " Please configure SOLR_AUTH_TYPE environment variable with the authentication type to be used."
+ echo " Currently supported authentication types are [kerberos, basic]"
+fi
+
+if [ -n "$SOLR_AUTH_TYPE" ] && [ -n "$SOLR_AUTHENTICATION_CLIENT_BUILDER" ]; then
+ echo "WARNING: SOLR_AUTHENTICATION_CLIENT_BUILDER and SOLR_AUTH_TYPE environment variables are configured together."
+ echo " Use SOLR_AUTH_TYPE environment variable to configure authentication type to be used. "
+ echo " Currently supported authentication types are [kerberos, basic]"
+ echo " The value of SOLR_AUTHENTICATION_CLIENT_BUILDER environment variable will be ignored"
+fi
+
+if [ -n "$SOLR_AUTH_TYPE" ]; then
+ case "$(echo $SOLR_AUTH_TYPE | awk '{print tolower($0)}')" in
+ basic)
+ SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"
+ ;;
+ kerberos)
+ SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.Krb5HttpClientBuilder"
+ ;;
+ *)
+ echo "ERROR: Value specified for SOLR_AUTH_TYPE environment variable is invalid."
+ exit 1
+ esac
+fi
+
+if [ "$SOLR_AUTHENTICATION_CLIENT_CONFIGURER" != "" ]; then
+ echo "WARNING: Found unsupported configuration variable SOLR_AUTHENTICATION_CLIENT_CONFIGURER"
+ echo " Please start using SOLR_AUTH_TYPE instead"
+fi
+if [ "$SOLR_AUTHENTICATION_CLIENT_BUILDER" != "" ]; then
+ AUTHC_CLIENT_BUILDER_ARG="-Dsolr.httpclient.builder.factory=$SOLR_AUTHENTICATION_CLIENT_BUILDER"
+fi
+AUTHC_OPTS="$AUTHC_CLIENT_BUILDER_ARG $SOLR_AUTHENTICATION_OPTS"
+
+# Set the SOLR_TOOL_HOST variable for use when connecting to a running Solr instance
+if [ "$SOLR_HOST" != "" ]; then
+ SOLR_TOOL_HOST="$SOLR_HOST"
+else
+ SOLR_TOOL_HOST="localhost"
+fi
+
+function print_usage() {
+ CMD="$1"
+ ERROR_MSG="$2"
+
+ if [ "$ERROR_MSG" != "" ]; then
+ echo -e "\nERROR: $ERROR_MSG\n"
+ fi
+
+ if [ -z "$CMD" ]; then
+ echo ""
+ echo "Usage: solr COMMAND OPTIONS"
+ echo " where COMMAND is one of: start, stop, restart, status, healthcheck, create, create_core, create_collection, delete, version, zk, auth, assert, config, autoscaling"
+ echo ""
+ echo " Standalone server example (start Solr running in the background on port 8984):"
+ echo ""
+ echo " ./solr start -p 8984"
+ echo ""
+ echo " SolrCloud example (start Solr running in SolrCloud mode using localhost:2181 to connect to Zookeeper, with 1g max heap size and remote Java debug options enabled):"
+ echo ""
+ echo " ./solr start -c -m 1g -z localhost:2181 -a \"-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044\""
+ echo ""
+ echo " Omit '-z localhost:2181' from the above command if you have defined ZK_HOST in solr.in.sh."
+ echo ""
+ echo "Pass -help after any COMMAND to see command-specific usage information,"
+ echo " such as: ./solr start -help or ./solr stop -help"
+ echo ""
+ elif [[ "$CMD" == "start" || "$CMD" == "restart" ]]; then
+ echo ""
+ echo "Usage: solr $CMD [-f] [-c] [-h hostname] [-p port] [-d directory] [-z zkHost] [-m memory] [-e example] [-s solr.solr.home] [-t solr.data.home] [-a \"additional-options\"] [-V]"
+ echo ""
+ echo " -f Start Solr in foreground; default starts Solr in the background"
+ echo " and sends stdout / stderr to solr-PORT-console.log"
+ echo ""
+ echo " -c or -cloud Start Solr in SolrCloud mode; if -z not supplied and ZK_HOST not defined in"
+ echo " solr.in.sh, an embedded ZooKeeper instance is started on Solr port+1000,"
+ echo " such as 9983 if Solr is bound to 8983"
+ echo ""
+ echo " -h Specify the hostname for this Solr instance"
+ echo ""
+ echo " -p Specify the port to start the Solr HTTP listener on; default is 8983"
+ echo " The specified port (SOLR_PORT) will also be used to determine the stop port"
+ echo " STOP_PORT=(\$SOLR_PORT-1000) and JMX RMI listen port RMI_PORT=(\$SOLR_PORT+10000). "
+ echo " For instance, if you set -p 8985, then the STOP_PORT=7985 and RMI_PORT=18985"
+ echo ""
+ echo " -d Specify the Solr server directory; defaults to server"
+ echo ""
+ echo " -z Zookeeper connection string; only used when running in SolrCloud mode using -c"
+ echo " If neither ZK_HOST is defined in solr.in.sh nor the -z parameter is specified,"
+ echo " an embedded ZooKeeper instance will be launched."
+ echo ""
+ echo " -m Sets the min (-Xms) and max (-Xmx) heap size for the JVM, such as: -m 4g"
+ echo " results in: -Xms4g -Xmx4g; by default, this script sets the heap size to 512m"
+ echo ""
+ echo " -s Sets the solr.solr.home system property; Solr will create core directories under"
+ echo " this directory. This allows you to run multiple Solr instances on the same host"
+ echo " while reusing the same server directory set using the -d parameter. If set, the"
+ echo " specified directory should contain a solr.xml file, unless solr.xml exists in Zookeeper."
+ echo " This parameter is ignored when running examples (-e), as the solr.solr.home depends"
+ echo " on which example is run. The default value is server/solr. If passed relative dir,"
+ echo " validation with current dir will be done, before trying default server/"
+ echo ""
+ echo " -t Sets the solr.data.home system property, where Solr will store index data in /data subdirectories."
+ echo " If not set, Solr uses solr.solr.home for config and data."
+ echo ""
+ echo " -e Name of the example to run; available examples:"
+ echo " cloud: SolrCloud example"
+ echo " techproducts: Comprehensive example illustrating many of Solr's core capabilities"
+ echo " dih: Data Import Handler"
+ echo " schemaless: Schema-less example"
+ echo ""
+ echo " -a Additional parameters to pass to the JVM when starting Solr, such as to setup"
+ echo " Java debug options. For example, to enable a Java debugger to attach to the Solr JVM"
+ echo " you could pass: -a \"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=18983\""
+ echo " In most cases, you should wrap the additional parameters in double quotes."
+ echo ""
+ echo " -j Additional parameters to pass to Jetty when starting Solr."
+ echo " For example, to add configuration folder that jetty should read"
+ echo " you could pass: -j \"--include-jetty-dir=/etc/jetty/custom/server/\""
+ echo " In most cases, you should wrap the additional parameters in double quotes."
+ echo ""
+ echo " -noprompt Don't prompt for input; accept all defaults when running examples that accept user input"
+ echo ""
+ echo " -v and -q Verbose (-v) or quiet (-q) logging. Sets default log level to DEBUG or WARN instead of INFO"
+ echo ""
+ echo " -V/-verbose Verbose messages from this script"
+ echo ""
+ elif [ "$CMD" == "stop" ]; then
+ echo ""
+ echo "Usage: solr stop [-k key] [-p port] [-V]"
+ echo ""
+ echo " -k Stop key; default is solrrocks"
+ echo ""
+ echo " -p Specify the port the Solr HTTP listener is bound to"
+ echo ""
+ echo " -all Find and stop all running Solr servers on this host"
+ echo ""
+ echo " -V/-verbose Verbose messages from this script"
+ echo ""
+ echo " NOTE: To see if any Solr servers are running, do: solr status"
+ echo ""
+ elif [ "$CMD" == "healthcheck" ]; then
+ echo ""
+ echo "Usage: solr healthcheck [-c collection] [-z zkHost] [-V]"
+ echo ""
+ echo "Can be run from remote (non-Solr) hosts, as long as a proper ZooKeeper connection is provided"
+ echo ""
+ echo " -c Collection to run healthcheck against."
+ echo ""
+ echo " -z Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.sh;"
+ echo " otherwise, default is localhost:9983"
+ echo ""
+ echo " -V Enable more verbose output"
+ echo ""
+ elif [ "$CMD" == "status" ]; then
+ echo ""
+ echo "Usage: solr status"
+ echo ""
+ echo " This command will show the status of all running Solr servers."
+ echo " It can only detect those Solr servers running on the current host."
+ echo ""
+ elif [ "$CMD" == "create" ]; then
+ echo ""
+ echo "Usage: solr create [-c name] [-d confdir] [-n configName] [-shards #] [-replicationFactor #] [-p port] [-V]"
+ echo ""
+ echo " Create a core or collection depending on whether Solr is running in standalone (core) or SolrCloud"
+ echo " mode (collection). In other words, this action detects which mode Solr is running in, and then takes"
+ echo " the appropriate action (either create_core or create_collection). For detailed usage instructions, do:"
+ echo ""
+ echo " bin/solr create_core -help"
+ echo ""
+ echo " or"
+ echo ""
+ echo " bin/solr create_collection -help"
+ echo ""
+ elif [ "$CMD" == "delete" ]; then
+ echo ""
+ echo "Usage: solr delete [-c name] [-deleteConfig true|false] [-p port] [-V]"
+ echo ""
+ echo " Deletes a core or collection depending on whether Solr is running in standalone (core) or SolrCloud"
+ echo " mode (collection). If you're deleting a collection in SolrCloud mode, the default behavior is to also"
+ echo " delete the configuration directory from Zookeeper so long as it is not being used by another collection."
+ echo " You can override this behavior by passing -deleteConfig false when running this command."
+ echo ""
+ echo " Can be run on remote (non-Solr) hosts, as long as a valid SOLR_HOST is provided in solr.in.sh"
+ echo ""
+ echo " -c Name of the core / collection to delete"
+ echo ""
+ echo " -deleteConfig Delete the configuration directory from Zookeeper; default is true"
+ echo ""
+ echo " -p Port of a local Solr instance where you want to delete the core/collection"
+ echo " If not specified, the script will search the local system for a running"
+ echo " Solr instance and will use the port of the first server it finds."
+ echo ""
+ echo " -V Enables more verbose output."
+ echo ""
+ elif [ "$CMD" == "create_core" ]; then
+ echo ""
+ echo "Usage: solr create_core [-c core] [-d confdir] [-p port] [-V]"
+ echo ""
+ echo "When a configSet is used, this can be run from remote (non-Solr) hosts. If pointing at a non-configSet directory, this"
+ echo "must be run from the host that you wish to create the core on"
+ echo ""
+ echo " -c Name of core to create"
+ echo ""
+ echo " -d Configuration directory to copy when creating the new core, built-in options are:"
+ echo ""
+ echo " _default: Minimal configuration, which supports enabling/disabling field-guessing support"
+ echo " sample_techproducts_configs: Example configuration with many optional features enabled to"
+ echo " demonstrate the full power of Solr"
+ echo ""
+ echo " If not specified, default is: _default"
+ echo ""
+ echo " Alternatively, you can pass the path to your own configuration directory instead of using"
+ echo " one of the built-in configurations, such as: bin/solr create_core -c mycore -d /tmp/myconfig"
+ echo ""
+ echo " -p Port of a local Solr instance where you want to create the new core"
+ echo " If not specified, the script will search the local system for a running"
+ echo " Solr instance and will use the port of the first server it finds."
+ echo ""
+ echo " -V Enable more verbose output."
+ echo ""
+ elif [ "$CMD" == "create_collection" ]; then
+ echo ""
+ echo "Usage: solr create_collection [-c collection] [-d confdir] [-n configName] [-shards #] [-replicationFactor #] [-p port] [-V]"
+ echo ""
+ echo "Can be run from remote (non-Solr) hosts, as long as a valid SOLR_HOST is provided in solr.in.sh"
+ echo " -c Name of collection to create"
+ echo ""
+ echo " -d Configuration directory to copy when creating the new collection, built-in options are:"
+ echo ""
+ echo " _default: Minimal configuration, which supports enabling/disabling field-guessing support"
+ echo " sample_techproducts_configs: Example configuration with many optional features enabled to"
+ echo " demonstrate the full power of Solr"
+ echo ""
+ echo " If not specified, default is: _default"
+ echo ""
+ echo " Alternatively, you can pass the path to your own configuration directory instead of using"
+ echo " one of the built-in configurations, such as: bin/solr create_collection -c mycoll -d /tmp/myconfig"
+ echo ""
+ echo " By default the script will upload the specified confdir directory into Zookeeper using the same"
+ echo " name as the collection (-c) option. Alternatively, if you want to reuse an existing directory"
+ echo " or create a confdir in Zookeeper that can be shared by multiple collections, use the -n option"
+ echo ""
+ echo " -n Name the configuration directory in Zookeeper; by default, the configuration"
+ echo " will be uploaded to Zookeeper using the collection name (-c), but if you want"
+ echo " to use an existing directory or override the name of the configuration in"
+ echo " Zookeeper, then use the -c option."
+ echo ""
+ echo " -shards <#> Number of shards to split the collection into; default is 1"
+ echo ""
+ echo " -replicationFactor <#> Number of copies of each document in the collection, default is 1 (no replication)"
+ echo ""
+ echo " -p Port of a local Solr instance where you want to create the new collection"
+ echo " If not specified, the script will search the local system for a running"
+ echo " Solr instance and will use the port of the first server it finds."
+ echo ""
+ echo " -V Enable more verbose output."
+ echo ""
+ elif [ "$CMD" == "zk" ]; then
+ print_short_zk_usage ""
+ echo " Can be run on remote (non-Solr) hosts, as long as valid ZK_HOST information is provided"
+ echo " Be sure to check the Solr logs in case of errors."
+ echo ""
+ echo " -z zkHost Optional Zookeeper connection string for all commands. If specified it"
+ echo " overrides the 'ZK_HOST=...'' defined in solr.in.sh."
+ echo ""
+ echo " -V Enable more verbose output."
+ echo ""
+ echo " upconfig uploads a configset from the local machine to Zookeeper. (Backcompat: -upconfig)"
+ echo ""
+ echo " downconfig downloads a configset from Zookeeper to the local machine. (Backcompat: -downconfig)"
+ echo ""
+ echo " -n configName Name of the configset in Zookeeper that will be the destination of"
+ echo " 'upconfig' and the source for 'downconfig'."
+ echo ""
+ echo " -d confdir The local directory the configuration will be uploaded from for"
+ echo " 'upconfig' or downloaded to for 'downconfig'. If 'confdir' is a child of"
+ echo " ...solr/server/solr/configsets' then the configs will be copied from/to"
+ echo " that directory. Otherwise it is interpreted as a simple local path."
+ echo ""
+ echo " cp copies files or folders to/from Zookeeper or Zokeeper -> Zookeeper"
+ echo " -r Recursively copy to . Command will fail if has children and "
+ echo " -r is not specified. Optional"
+ echo ""
+ echo " , : [file:][/]path/to/local/file or zk:/path/to/zk/node"
+ echo " NOTE: and may both be Zookeeper resources prefixed by 'zk:'"
+ echo " When is a zk resource, may be '.'"
+ echo " If ends with '/', then will be a local folder or parent znode and the last"
+ echo " element of the path will be appended unless also ends in a slash. "
+ echo " may be zk:, which may be useful when using the cp -r form to backup/restore "
+ echo " the entire zk state."
+ echo " You must enclose local paths that end in a wildcard in quotes or just"
+ echo " end the local path in a slash. That is,"
+ echo " 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181' is equivalent to"
+ echo " 'bin/solr zk cp -r \"/some/dir/*\" zk:/ -z localhost:2181'"
+ echo " but 'bin/solr zk cp -r /some/dir/* zk:/ -z localhost:2181' will throw an error"
+ echo ""
+ echo " here's an example of backup/restore for a ZK configuration:"
+ echo " to copy to local: 'bin/solr zk cp -r zk:/ /some/dir -z localhost:2181'"
+ echo " to restore to ZK: 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181'"
+ echo ""
+ echo " The 'file:' prefix is stripped, thus 'file:/wherever' specifies an absolute local path and"
+ echo " 'file:somewhere' specifies a relative local path. All paths on Zookeeper are absolute."
+ echo ""
+ echo " Zookeeper nodes CAN have data, so moving a single file to a parent znode"
+ echo " will overlay the data on the parent Znode so specifying the trailing slash"
+ echo " can be important."
+ echo ""
+ echo " Wildcards are supported when copying from local, trailing only and must be quoted."
+ echo ""
+ echo " rm deletes files or folders on Zookeeper"
+ echo " -r Recursively delete if is a directory. Command will fail if "
+ echo " has children and -r is not specified. Optional"
+ echo " : [zk:]/path/to/zk/node. may not be the root ('/')"
+ echo ""
+ echo " mv moves (renames) znodes on Zookeeper"
+ echo " , : Zookeeper nodes, the 'zk:' prefix is optional."
+ echo " If ends with '/', then will be a parent znode"
+ echo " and the last element of the path will be appended."
+ echo " Zookeeper nodes CAN have data, so moving a single file to a parent znode"
+ echo " will overlay the data on the parent Znode so specifying the trailing slash"
+ echo " is important."
+ echo ""
+ echo " ls lists the znodes on Zookeeper"
+ echo " -r recursively descends the path listing all znodes. Optional"
+ echo " : The Zookeeper path to use as the root."
+ echo ""
+ echo " Only the node names are listed, not data"
+ echo ""
+ echo " mkroot makes a znode in Zookeeper with no data. Can be used to make a path of arbitrary"
+ echo " depth but primarily intended to create a 'chroot'."
+ echo ""
+ echo " : The Zookeeper path to create. Leading slash is assumed if not present."
+ echo " Intermediate nodes are created as needed if not present."
+ echo ""
+ elif [ "$CMD" == "auth" ]; then
+ echo ""
+ echo "Usage: solr auth enable [-type basicAuth] -credentials user:pass [-blockUnknown ] [-updateIncludeFileOnly ] [-V]"
+ echo " solr auth enable [-type basicAuth] -prompt [-blockUnknown ] [-updateIncludeFileOnly ] [-V]"
+ echo " solr auth enable -type kerberos -config \"\" [-updateIncludeFileOnly ] [-V]"
+ echo " solr auth disable [-updateIncludeFileOnly ] [-V]"
+ echo ""
+ echo " Updates or enables/disables authentication. Must be run on the machine hosting Solr."
+ echo ""
+ echo " -type The authentication mechanism (basicAuth or kerberos) to enable. Defaults to 'basicAuth'."
+ echo ""
+ echo " -credentials The username and password of the initial user. Applicable for basicAuth only."
+ echo " Note: only one of -prompt or -credentials must be provided"
+ echo ""
+ echo " -config \"\" Configuration parameters (Solr startup parameters). Required and applicable only for Kerberos"
+ echo ""
+ echo " -prompt Prompts the user to provide the credentials. Applicable for basicAuth only."
+ echo " Note: only one of -prompt or -credentials must be provided"
+ echo ""
+ echo " -blockUnknown When true, this blocks out access to unauthenticated users. When not provided,"
+ echo " this defaults to false (i.e. unauthenticated users can access all endpoints, except the"
+ echo " operations like collection-edit, security-edit, core-admin-edit etc.). Check the reference"
+ echo " guide for Basic Authentication for more details. Applicable for basicAuth only."
+ echo ""
+ echo " -updateIncludeFileOnly Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
+ echo " authentication (i.e. don't update security.json)"
+ echo ""
+ echo " -z zkHost Zookeeper connection string. Unnecessary if ZK_HOST is defined in solr.in.sh."
+ echo ""
+ echo " -d Specify the Solr server directory"
+ echo ""
+ echo " -s Specify the Solr home directory. This is where any credentials or authentication"
+ echo " configuration files (e.g. basicAuth.conf) would be placed."
+ echo ""
+ echo " -V Enable more verbose output."
+ echo ""
+ fi
+} # end print_usage
+
+function print_short_zk_usage() {
+
+ if [ "$1" != "" ]; then
+ echo -e "\nERROR: $1\n"
+ fi
+
+ echo " Usage: solr zk upconfig|downconfig -d -n [-z zkHost]"
+ echo " solr zk cp [-r] [-z zkHost]"
+ echo " solr zk rm [-r] [-z zkHost]"
+ echo " solr zk mv [-z zkHost]"
+ echo " solr zk ls [-r] [-z zkHost]"
+ echo " solr zk mkroot [-z zkHost]"
+ echo ""
+
+ if [ "$1" == "" ]; then
+ echo "Type bin/solr zk -help for full usage help"
+ else
+ exit 1
+ fi
+}
+
+# used to show the script is still alive when waiting on work to complete
+function spinner() {
+ local pid=$1
+ local delay=0.5
+ local spinstr='|/-\'
+ while [ "$(ps aux | awk '{print $2}' | grep -w $pid)" ]; do
+ local temp=${spinstr#?}
+ printf " [%c] " "$spinstr"
+ local spinstr=$temp${spinstr%"$temp"}
+ sleep $delay
+ printf "\b\b\b\b\b\b"
+ done
+ printf " \b\b\b\b"
+}
+
+# given a port, find the pid for a Solr process
+function solr_pid_by_port() {
+ THE_PORT="$1"
+ if [ -e "$SOLR_PID_DIR/solr-$THE_PORT.pid" ]; then
+ PID=`cat "$SOLR_PID_DIR/solr-$THE_PORT.pid"`
+ CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $PID | sort -r | tr -d ' '`
+ if [ "$CHECK_PID" != "" ]; then
+ local solrPID=$PID
+ fi
+ fi
+ echo "$solrPID"
+}
+
+# extract the value of the -Djetty.port parameter from a running Solr process
+function jetty_port() {
+ SOLR_PID="$1"
+ SOLR_PROC=`ps auxww | grep -w $SOLR_PID | grep start\.jar | grep jetty\.port`
+ IFS=' ' read -a proc_args <<< "$SOLR_PROC"
+ for arg in "${proc_args[@]}"
+ do
+ IFS='=' read -a pair <<< "$arg"
+ if [ "${pair[0]}" == "-Djetty.port" ]; then
+ local jetty_port="${pair[1]}"
+ break
+ fi
+ done
+ echo "$jetty_port"
+} # end jetty_port func
+
+# run a Solr command-line tool using the SolrCLI class;
+# useful for doing cross-platform work from the command-line using Java
+function run_tool() {
+
+ "$JAVA" $SOLR_SSL_OPTS $AUTHC_OPTS $SOLR_ZK_CREDS_AND_ACLS -Dsolr.install.dir="$SOLR_TIP" \
+ -Dlog4j.configurationFile="file:$DEFAULT_SERVER_DIR/resources/log4j2-console.xml" \
+ -classpath "$DEFAULT_SERVER_DIR/solr-webapp/webapp/WEB-INF/lib/*:$DEFAULT_SERVER_DIR/lib/ext/*:$DEFAULT_SERVER_DIR/lib/*" \
+ org.apache.solr.util.SolrCLI "$@"
+
+ return $?
+} # end run_tool function
+
+# get information about any Solr nodes running on this host
+function get_info() {
+ CODE=4
+ # first, see if Solr is running
+ numSolrs=`find "$SOLR_PID_DIR" -name "solr-*.pid" -type f | wc -l | tr -d ' '`
+ if [ "$numSolrs" != "0" ]; then
+ echo -e "\nFound $numSolrs Solr nodes: "
+ while read PIDF
+ do
+ ID=`cat "$PIDF"`
+ port=`jetty_port "$ID"`
+ if [ "$port" != "" ]; then
+ echo -e "\nSolr process $ID running on port $port"
+ run_tool status -solr "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port/solr"
+ CODE=$?
+ echo ""
+ else
+ echo -e "\nSolr process $ID from $PIDF not found."
+ CODE=1
+ fi
+ done < <(find "$SOLR_PID_DIR" -name "solr-*.pid" -type f)
+ else
+ # no pid files but check using ps just to be sure
+ numSolrs=`ps auxww | grep start\.jar | grep solr\.solr\.home | grep -v grep | wc -l | sed -e 's/^[ \t]*//'`
+ if [ "$numSolrs" != "0" ]; then
+ echo -e "\nFound $numSolrs Solr nodes: "
+ PROCESSES=$(ps auxww | grep start\.jar | grep solr\.solr\.home | grep -v grep | awk '{print $2}' | sort -r)
+ for ID in $PROCESSES
+ do
+ port=`jetty_port "$ID"`
+ if [ "$port" != "" ]; then
+ echo ""
+ echo "Solr process $ID running on port $port"
+ run_tool status -solr "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$port/solr"
+ CODE=$?
+ echo ""
+ fi
+ done
+ else
+ echo -e "\nNo Solr nodes are running.\n"
+ CODE=3
+ fi
+ fi
+
+ return $CODE
+} # end get_info
+
+# tries to gracefully stop Solr using the Jetty
+# stop command and if that fails, then uses kill -9
+function stop_solr() {
+
+ DIR="$1"
+ SOLR_PORT="$2"
+ THIS_STOP_PORT="${STOP_PORT:-$(expr $SOLR_PORT - 1000)}"
+ STOP_KEY="$3"
+ SOLR_PID="$4"
+
+ if [ "$SOLR_PID" != "" ]; then
+ echo -e "Sending stop command to Solr running on port $SOLR_PORT ... waiting up to $SOLR_STOP_WAIT seconds to allow Jetty process $SOLR_PID to stop gracefully."
+ "$JAVA" $SOLR_SSL_OPTS $AUTHC_OPTS -jar "$DIR/start.jar" "STOP.PORT=$THIS_STOP_PORT" "STOP.KEY=$STOP_KEY" --stop || true
+ (loops=0
+ while true
+ do
+ CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $SOLR_PID | sort -r | tr -d ' '`
+ if [ "$CHECK_PID" != "" ]; then
+ slept=$((loops * 2))
+ if [ $slept -lt $SOLR_STOP_WAIT ]; then
+ sleep 2
+ loops=$[$loops+1]
+ else
+ exit # subshell!
+ fi
+ else
+ exit # subshell!
+ fi
+ done) &
+ spinner $!
+ rm -f "$SOLR_PID_DIR/solr-$SOLR_PORT.pid"
+ else
+ echo -e "No Solr nodes found to stop."
+ exit 0
+ fi
+
+ CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $SOLR_PID | sort -r | tr -d ' '`
+ if [ "$CHECK_PID" != "" ]; then
+ echo -e "Solr process $SOLR_PID is still running; forcefully killing it now."
+ kill -9 $SOLR_PID
+ echo "Killed process $SOLR_PID"
+ rm -f "$SOLR_PID_DIR/solr-$SOLR_PORT.pid"
+ sleep 1
+ fi
+
+ CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $SOLR_PID | sort -r | tr -d ' '`
+ if [ "$CHECK_PID" != "" ]; then
+ echo "ERROR: Failed to kill previous Solr Java process $SOLR_PID ... script fails."
+ exit 1
+ fi
+} # end stop_solr
+
+if [ $# -eq 1 ]; then
+ case $1 in
+ -help|-usage|-h|--help)
+ print_usage ""
+ exit
+ ;;
+ -info|-i|status)
+ get_info
+ exit $?
+ ;;
+ -version|-v|version)
+ run_tool version
+ exit
+ ;;
+ esac
+fi
+
+if [ $# -gt 0 ]; then
+ # if first arg starts with a dash (and it's not -help or -info),
+ # then assume they are starting Solr, such as: solr -f
+ if [[ $1 == -* ]]; then
+ SCRIPT_CMD="start"
+ else
+ SCRIPT_CMD="$1"
+ shift
+ fi
+else
+ # no args - just show usage and exit
+ print_usage ""
+ exit
+fi
+
+if [ "$SCRIPT_CMD" == "status" ]; then
+ # hacky - the script hits this if the user passes additional args with the status command,
+ # which is not supported but also not worth complaining about either
+ get_info
+ exit
+fi
+
+# assert tool
+if [ "$SCRIPT_CMD" == "assert" ]; then
+ run_tool assert $*
+ exit $?
+fi
+
+# run a healthcheck and exit if requested
+if [ "$SCRIPT_CMD" == "healthcheck" ]; then
+
+ VERBOSE=""
+
+ if [ $# -gt 0 ]; then
+ while true; do
+ case "$1" in
+ -c|-collection)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Collection name is required when using the $1 option!"
+ exit 1
+ fi
+ HEALTHCHECK_COLLECTION="$2"
+ shift 2
+ ;;
+ -z|-zkhost)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "ZooKeeper connection string is required when using the $1 option!"
+ exit 1
+ fi
+ ZK_HOST="$2"
+ shift 2
+ ;;
+ -help|-usage)
+ print_usage "$SCRIPT_CMD"
+ exit 0
+ ;;
+ -V|--verbose)
+ VERBOSE="-verbose"
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ if [ "$1" != "" ]; then
+ print_usage "$SCRIPT_CMD" "Unrecognized or misplaced argument: $1!"
+ exit 1
+ else
+ break # out-of-args, stop looping
+ fi
+ ;;
+ esac
+ done
+ fi
+
+ if [ -z "$ZK_HOST" ]; then
+ ZK_HOST=localhost:9983
+ fi
+
+ if [ -z "$HEALTHCHECK_COLLECTION" ]; then
+ echo "collection parameter is required!"
+ print_usage "healthcheck"
+ exit 1
+ fi
+
+ run_tool healthcheck -zkHost "$ZK_HOST" -collection "$HEALTHCHECK_COLLECTION" $VERBOSE
+
+ exit $?
+fi
+
+if [[ "$SCRIPT_CMD" == "config" ]]; then
+ CONFIG_PARAMS=()
+
+ if [ $# -gt 0 ]; then
+ while true; do
+ case "$1" in
+ -z|-zkhost|-zkHost)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "ZooKeeper connection string is required when using the $1 option!"
+ exit 1
+ fi
+ ZK_HOST="$2"
+ shift 2
+ ;;
+ -s|-scheme)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "URL scheme is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_URL_SCHEME="$2"
+ shift 2
+ ;;
+ *) # Pass through all other params
+ if [ "$1" != "" ]; then
+ CONFIG_PARAMS+=($1)
+ shift
+ else
+ break
+ fi
+ ;;
+ esac
+ done
+ fi
+ if [[ -n "$ZK_HOST" ]]; then
+ CONFIG_PARAMS+=("-z" "$ZK_HOST")
+ fi
+ if [[ -n "$SOLR_URL_SCHEME" ]]; then
+ CONFIG_PARAMS+=("-scheme" "$SOLR_URL_SCHEME")
+ fi
+ run_tool config "${CONFIG_PARAMS[@]}"
+ exit $?
+fi
+
+# create a core or collection
+if [[ "$SCRIPT_CMD" == "create" || "$SCRIPT_CMD" == "create_core" || "$SCRIPT_CMD" == "create_collection" ]]; then
+
+ CREATE_NUM_SHARDS=1
+ CREATE_REPFACT=1
+ FORCE=false
+ VERBOSE=""
+
+ if [ $# -gt 0 ]; then
+ while true; do
+ case "$1" in
+ -c|-core|-collection)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "name is required when using the $1 option!"
+ exit 1
+ fi
+ CREATE_NAME="$2"
+ shift 2
+ ;;
+ -n|-confname)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Configuration name is required when using the $1 option!"
+ exit 1
+ fi
+ CREATE_CONFNAME="$2"
+ shift 2
+ ;;
+ -d|-confdir)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Configuration directory is required when using the $1 option!"
+ exit 1
+ fi
+ CREATE_CONFDIR="$2"
+ shift 2
+ ;;
+ -s|-shards)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Shard count is required when using the $1 option!"
+ exit 1
+ fi
+ CREATE_NUM_SHARDS="$2"
+ shift 2
+ ;;
+ -rf|-replicationFactor)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Replication factor is required when using the $1 option!"
+ exit 1
+ fi
+ CREATE_REPFACT="$2"
+ shift 2
+ ;;
+ -p|-port)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Solr port is required when using the $1 option!"
+ exit 1
+ fi
+ CREATE_PORT="$2"
+ shift 2
+ ;;
+ -V|--verbose)
+ VERBOSE="-verbose"
+ shift
+ ;;
+ -force)
+ FORCE=true
+ shift
+ ;;
+ -help|-usage)
+ print_usage "$SCRIPT_CMD"
+ exit 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ if [ "$1" != "" ]; then
+ print_usage "$SCRIPT_CMD" "Unrecognized or misplaced argument: $1!"
+ exit 1
+ else
+ break # out-of-args, stop looping
+ fi
+ ;;
+ esac
+ done
+ fi
+
+ if [ -z "$CREATE_CONFDIR" ]; then
+ CREATE_CONFDIR='_default'
+ fi
+
+ # validate the confdir arg (if provided)
+ if [[ ! -d "$SOLR_TIP/server/solr/configsets/$CREATE_CONFDIR" && ! -d "$CREATE_CONFDIR" ]]; then
+ echo -e "\nSpecified configuration directory $CREATE_CONFDIR not found!\n"
+ exit 1
+ fi
+
+ if [ -z "$CREATE_NAME" ]; then
+ echo "Name (-c) argument is required!"
+ print_usage "$SCRIPT_CMD"
+ exit 1
+ fi
+
+ if [ -z "$CREATE_PORT" ]; then
+ for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r`
+ do
+ port=`jetty_port "$ID"`
+ if [ "$port" != "" ]; then
+ CREATE_PORT=$port
+ break
+ fi
+ done
+ fi
+
+ if [ -z "$CREATE_PORT" ]; then
+ echo "Failed to determine the port of a local Solr instance, cannot create $CREATE_NAME!"
+ exit 1
+ fi
+
+ if [[ "$CREATE_CONFDIR" == "_default" ]] && ([[ "$CREATE_CONFNAME" == "" ]] || [[ "$CREATE_CONFNAME" == "_default" ]]); then
+ echo "WARNING: Using _default configset with data driven schema functionality. NOT RECOMMENDED for production use."
+ echo " To turn off: bin/solr config -c $CREATE_NAME -p $CREATE_PORT -action set-user-property -property update.autoCreateFields -value false"
+ fi
+
+ if [[ "$(whoami)" == "root" ]] && [[ "$FORCE" == "false" ]] ; then
+ echo "WARNING: Creating cores as the root user can cause Solr to fail and is not advisable. Exiting."
+ echo " If you started Solr as root (not advisable either), force core creation by adding argument -force"
+ exit 1
+ fi
+ if [ "$SCRIPT_CMD" == "create_core" ]; then
+ run_tool create_core -name "$CREATE_NAME" -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$CREATE_PORT/solr" \
+ -confdir "$CREATE_CONFDIR" -configsetsDir "$SOLR_TIP/server/solr/configsets" \
+ $VERBOSE
+ exit $?
+ else
+ run_tool "$SCRIPT_CMD" -name "$CREATE_NAME" -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$CREATE_PORT/solr" \
+ -shards "$CREATE_NUM_SHARDS" -replicationFactor "$CREATE_REPFACT" \
+ -confname "$CREATE_CONFNAME" -confdir "$CREATE_CONFDIR" \
+ -configsetsDir "$SOLR_TIP/server/solr/configsets" \
+ $VERBOSE
+ exit $?
+ fi
+fi
+
+# delete a core or collection
+if [[ "$SCRIPT_CMD" == "delete" ]]; then
+
+ VERBOSE=""
+
+ if [ $# -gt 0 ]; then
+ while true; do
+ case "$1" in
+ -c|-core|-collection)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "name is required when using the $1 option!"
+ exit 1
+ fi
+ DELETE_NAME="$2"
+ shift 2
+ ;;
+ -p|-port)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Solr port is required when using the $1 option!"
+ exit 1
+ fi
+ DELETE_PORT="$2"
+ shift 2
+ ;;
+ -deleteConfig)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "true|false is required when using the $1 option!"
+ exit 1
+ fi
+ DELETE_CONFIG="$2"
+ shift 2
+ ;;
+ -V|--verbose)
+ VERBOSE="-verbose"
+ shift
+ ;;
+ -help|-usage)
+ print_usage "$SCRIPT_CMD"
+ exit 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ if [ "$1" != "" ]; then
+ print_usage "$SCRIPT_CMD" "Unrecognized or misplaced argument: $1!"
+ exit 1
+ else
+ break # out-of-args, stop looping
+ fi
+ ;;
+ esac
+ done
+ fi
+
+ if [ -z "$DELETE_NAME" ]; then
+ echo "Name (-c) argument is required!"
+ print_usage "$SCRIPT_CMD"
+ exit 1
+ fi
+
+ # If not defined, use the collection name for the name of the configuration in Zookeeper
+ if [ -z "$DELETE_CONFIG" ]; then
+ DELETE_CONFIG=true
+ fi
+
+ if [ -z "$DELETE_PORT" ]; then
+ for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r`
+ do
+ port=`jetty_port "$ID"`
+ if [ "$port" != "" ]; then
+ DELETE_PORT=$port
+ break
+ fi
+ done
+ fi
+
+ if [ -z "$DELETE_PORT" ]; then
+ echo "Failed to determine the port of a local Solr instance, cannot delete $DELETE_NAME!"
+ exit 1
+ fi
+
+ run_tool delete -name "$DELETE_NAME" -deleteConfig "$DELETE_CONFIG" \
+ -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$DELETE_PORT/solr" \
+ $VERBOSE
+ exit $?
+fi
+
+ZK_RECURSE=false
+# Zookeeper file maintenance (upconfig, downconfig, files up/down etc.)
+# It's a little clumsy to have the parsing go round and round for upconfig and downconfig, but that's
+# necessary for back-compat
+if [[ "$SCRIPT_CMD" == "zk" ]]; then
+
+ VERBOSE=""
+
+ if [ $# -gt 0 ]; then
+ while true; do
+ case "$1" in
+ -upconfig|upconfig|-downconfig|downconfig|cp|rm|mv|ls|mkroot)
+ if [ "${1:0:1}" == "-" ]; then
+ ZK_OP=${1:1}
+ else
+ ZK_OP=$1
+ fi
+ shift 1
+ ;;
+ -z|-zkhost)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_short_zk_usage "$SCRIPT_CMD" "ZooKeeper connection string is required when using the $1 option!"
+ fi
+ ZK_HOST="$2"
+ shift 2
+ ;;
+ -n|-confname)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_short_zk_usage "$SCRIPT_CMD" "Configuration name is required when using the $1 option!"
+ fi
+ CONFIGSET_CONFNAME="$2"
+ shift 2
+ ;;
+ -d|-confdir)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_short_zk_usage "$SCRIPT_CMD" "Configuration directory is required when using the $1 option!"
+ fi
+ CONFIGSET_CONFDIR="$2"
+ shift 2
+ ;;
+ -r)
+ ZK_RECURSE="true"
+ shift
+ ;;
+ -V|--verbose)
+ VERBOSE="-verbose"
+ shift
+ ;;
+ -help|-usage|-h)
+ print_usage "$SCRIPT_CMD"
+ exit 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *) # Pick up or params for rm, ls, cp, mv, mkroot.
+ if [ "$1" == "" ]; then
+ break # out-of-args, stop looping
+ fi
+ if [ -z "$ZK_SRC" ]; then
+ ZK_SRC=$1
+ else
+ if [ -z "$ZK_DST" ]; then
+ ZK_DST=$1
+ else
+ print_short_zk_usage "Unrecognized or misplaced command $1. 'cp' with trailing asterisk requires quoting, see help text."
+ fi
+ fi
+ shift
+ ;;
+ esac
+ done
+ fi
+
+ if [ -z "$ZK_OP" ]; then
+ print_short_zk_usage "Zookeeper operation (one of 'upconfig', 'downconfig', 'rm', 'mv', 'cp', 'ls', 'mkroot') is required!"
+ fi
+
+ if [ -z "$ZK_HOST" ]; then
+ print_short_zk_usage "Zookeeper address (-z) argument is required or ZK_HOST must be specified in the solr.in.sh file."
+ fi
+
+ if [[ "$ZK_OP" == "upconfig" || "$ZK_OP" == "downconfig" ]]; then
+ if [ -z "$CONFIGSET_CONFDIR" ]; then
+ print_short_zk_usage "Local directory of the configset (-d) argument is required!"
+ fi
+
+ if [ -z "$CONFIGSET_CONFNAME" ]; then
+ print_short_zk_usage "Configset name on Zookeeper (-n) argument is required!"
+ fi
+ fi
+
+ if [[ "$ZK_OP" == "cp" || "$ZK_OP" == "mv" ]]; then
+ if [[ -z "$ZK_SRC" || -z "$ZK_DST" ]]; then
+ print_short_zk_usage " and must be specified when using either the 'mv' or 'cp' commands."
+ fi
+ if [[ "$ZK_OP" == "cp" && "${ZK_SRC:0:3}" != "zk:" && "${ZK_DST:0:3}" != "zk:" ]]; then
+ print_short_zk_usage "One of the source or desintation paths must be prefixed by 'zk:' for the 'cp' command."
+ fi
+ fi
+
+ if [[ "$ZK_OP" == "mkroot" ]]; then
+ if [[ -z "$ZK_SRC" ]]; then
+ print_short_zk_usage " must be specified when using the 'mkroot' command."
+ fi
+ fi
+
+
+ case "$ZK_OP" in
+ upconfig)
+ run_tool "$ZK_OP" -confname "$CONFIGSET_CONFNAME" -confdir "$CONFIGSET_CONFDIR" -zkHost "$ZK_HOST" -configsetsDir "$SOLR_TIP/server/solr/configsets" $VERBOSE
+ ;;
+ downconfig)
+ run_tool "$ZK_OP" -confname "$CONFIGSET_CONFNAME" -confdir "$CONFIGSET_CONFDIR" -zkHost "$ZK_HOST" $VERBOSE
+ ;;
+ rm)
+ if [ -z "$ZK_SRC" ]; then
+ print_short_zk_usage "Zookeeper path to remove must be specified when using the 'rm' command"
+ fi
+ run_tool "$ZK_OP" -path "$ZK_SRC" -zkHost "$ZK_HOST" -recurse "$ZK_RECURSE" $VERBOSE
+ ;;
+ mv)
+ run_tool "$ZK_OP" -src "$ZK_SRC" -dst "$ZK_DST" -zkHost "$ZK_HOST" $VERBOSE
+ ;;
+ cp)
+ run_tool "$ZK_OP" -src "$ZK_SRC" -dst "$ZK_DST" -zkHost "$ZK_HOST" -recurse "$ZK_RECURSE" $VERBOSE
+ ;;
+ ls)
+ if [ -z "$ZK_SRC" ]; then
+ print_short_zk_usage "Zookeeper path to list must be specified when using the 'ls' command"
+ fi
+ run_tool "$ZK_OP" -path "$ZK_SRC" -recurse "$ZK_RECURSE" -zkHost "$ZK_HOST" $VERBOSE
+ ;;
+ mkroot)
+ if [ -z "$ZK_SRC" ]; then
+ print_short_zk_usage "Zookeeper path to list must be specified when using the 'mkroot' command"
+ fi
+ run_tool "$ZK_OP" -path "$ZK_SRC" -zkHost "$ZK_HOST" $VERBOSE
+ ;;
+ *)
+ print_short_zk_usage "Unrecognized Zookeeper operation $ZK_OP"
+ ;;
+ esac
+
+ exit $?
+fi
+
+
+if [[ "$SCRIPT_CMD" == "autoscaling" ]]; then
+ run_tool autoscaling $@
+ exit $?
+fi
+
+if [[ "$SCRIPT_CMD" == "auth" ]]; then
+
+ VERBOSE=""
+
+ declare -a AUTH_PARAMS
+ if [ $# -gt 0 ]; then
+ while true; do
+ case "$1" in
+ enable|disable)
+ AUTH_OP=$1
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "$AUTH_OP")
+ shift
+ ;;
+ -z|-zkhost|zkHost)
+ ZK_HOST="$2"
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-zkHost" "$ZK_HOST")
+ shift 2
+ ;;
+ -t|-type)
+ AUTH_TYPE="$2"
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-type" "$AUTH_TYPE")
+ shift 2
+ ;;
+ -credentials)
+ AUTH_CREDENTIALS="$2"
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-credentials" "$AUTH_CREDENTIALS")
+ shift 2
+ ;;
+ -config)
+ AUTH_CONFIG="`echo $2| base64`"
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-config" "$AUTH_CONFIG")
+ shift 2
+ ;;
+ -solrIncludeFile)
+ SOLR_INCLUDE="$2"
+ shift 2
+ ;;
+ -prompt)
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-prompt" "$2")
+ shift
+ ;;
+ -blockUnknown)
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-blockUnknown" "$2")
+ shift
+ break
+ ;;
+ -updateIncludeFileOnly)
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-updateIncludeFileOnly" "$2")
+ shift
+ break
+ ;;
+ -V|--verbose)
+ VERBOSE="-verbose"
+ shift
+ ;;
+ -d|-dir)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Server directory is required when using the $1 option!"
+ exit 1
+ fi
+
+ if [[ "$2" == "." || "$2" == "./" || "$2" == ".." || "$2" == "../" ]]; then
+ SOLR_SERVER_DIR="$(pwd)/$2"
+ else
+ # see if the arg value is relative to the tip vs full path
+ if [[ "$2" != /* ]] && [[ -d "$SOLR_TIP/$2" ]]; then
+ SOLR_SERVER_DIR="$SOLR_TIP/$2"
+ else
+ SOLR_SERVER_DIR="$2"
+ fi
+ fi
+ # resolve it to an absolute path
+ SOLR_SERVER_DIR="$(cd "$SOLR_SERVER_DIR"; pwd)"
+ shift 2
+ ;;
+ -s|-solr.home)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Solr home directory is required when using the $1 option!"
+ exit 1
+ fi
+
+ SOLR_HOME="$2"
+ shift 2
+ ;;
+ -help|-usage|-h)
+ print_usage "$SCRIPT_CMD"
+ exit 0
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ shift
+ break
+ ;;
+ esac
+ done
+ fi
+
+ if [ -z "$SOLR_SERVER_DIR" ]; then
+ SOLR_SERVER_DIR="$DEFAULT_SERVER_DIR"
+ fi
+ if [ ! -e "$SOLR_SERVER_DIR" ]; then
+ echo -e "\nSolr server directory $SOLR_SERVER_DIR not found!\n"
+ exit 1
+ fi
+
+ if [ -z "$SOLR_HOME" ]; then
+ SOLR_HOME="$SOLR_SERVER_DIR/solr"
+ elif [[ $SOLR_HOME != /* ]]; then
+ if [[ -d "`pwd`/$SOLR_HOME" ]]; then
+ SOLR_HOME="$(pwd)/$SOLR_HOME"
+ elif [[ -d "$SOLR_SERVER_DIR/$SOLR_HOME" ]]; then
+ SOLR_HOME="$SOLR_SERVER_DIR/$SOLR_HOME"
+ SOLR_PID_DIR="$SOLR_HOME"
+ fi
+ fi
+
+ if [ -z "$AUTH_OP" ]; then
+ print_usage "$SCRIPT_CMD"
+ exit 0
+ fi
+
+ AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-solrIncludeFile" "$SOLR_INCLUDE")
+
+ if [ -z "$AUTH_PORT" ]; then
+ for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r`
+ do
+ port=`jetty_port "$ID"`
+ if [ "$port" != "" ]; then
+ AUTH_PORT=$port
+ break
+ fi
+ done
+ fi
+ run_tool auth ${AUTH_PARAMS[@]} -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$AUTH_PORT/solr" -authConfDir "$SOLR_HOME" $VERBOSE
+ exit $?
+fi
+
+
+# verify the command given is supported
+if [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "restart" ] && [ "$SCRIPT_CMD" != "status" ] && [ "$SCRIPT_CMD" != "assert" ]; then
+ print_usage "" "$SCRIPT_CMD is not a valid command!"
+ exit 1
+fi
+
+#Check current Ulimits for Open Files and Max Processes. Warn if they are below the recommended values.
+
+if [ -z "$SOLR_RECOMMENDED_MAX_PROCESSES" ]; then
+ SOLR_RECOMMENDED_MAX_PROCESSES=65000
+fi
+
+if [ -z "$SOLR_RECOMMENDED_OPEN_FILES" ]; then
+ SOLR_RECOMMENDED_OPEN_FILES=65000
+fi
+
+if [ -z "$SOLR_ULIMIT_CHECKS" ] || [ "$SOLR_ULIMIT_CHECKS" != "false" ]; then
+ if [ "$SCRIPT_CMD" == "start" ] || [ "$SCRIPT_CMD" == "restart" ] || [ "$SCRIPT_CMD" == "status" ]; then
+ if hash ulimit 2>/dev/null; then
+ openFiles=$(ulimit -n)
+ maxProcs=$(ulimit -u)
+ if [ $openFiles != "unlimited" ] && [ $openFiles -lt "$SOLR_RECOMMENDED_OPEN_FILES" ]; then
+ echo "*** [WARN] *** Your open file limit is currently $openFiles. "
+ echo " It should be set to $SOLR_RECOMMENDED_OPEN_FILES to avoid operational disruption. "
+ echo " If you no longer wish to see this warning, set SOLR_ULIMIT_CHECKS to false in your profile or solr.in.sh"
+ fi
+
+ if [ $maxProcs != "unlimited" ] && [ $maxProcs -lt "$SOLR_RECOMMENDED_MAX_PROCESSES" ]; then
+ echo "*** [WARN] *** Your Max Processes Limit is currently $maxProcs. "
+ echo " It should be set to $SOLR_RECOMMENDED_MAX_PROCESSES to avoid operational disruption. "
+ echo " If you no longer wish to see this warning, set SOLR_ULIMIT_CHECKS to false in your profile or solr.in.sh"
+ fi
+ else
+ echo "Could not check ulimits for processes and open files, recommended values are"
+ echo " max processes: $SOLR_RECOMMENDED_MAX_PROCESSES "
+ echo " open files: $SOLR_RECOMMENDED_OPEN_FILES"
+ fi
+ fi
+fi
+
+# Run in foreground (default is to run in the background)
+FG="false"
+FORCE=false
+noprompt=false
+SOLR_OPTS=($SOLR_OPTS)
+PASS_TO_RUN_EXAMPLE=
+
+if [ $# -gt 0 ]; then
+ while true; do
+ case "$1" in
+ -c|-cloud)
+ SOLR_MODE="solrcloud"
+ PASS_TO_RUN_EXAMPLE+=" -c"
+ shift
+ ;;
+ -d|-dir)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Server directory is required when using the $1 option!"
+ exit 1
+ fi
+
+ if [[ "$2" == "." || "$2" == "./" || "$2" == ".." || "$2" == "../" ]]; then
+ SOLR_SERVER_DIR="$(pwd)/$2"
+ else
+ # see if the arg value is relative to the tip vs full path
+ if [[ "$2" != /* ]] && [[ -d "$SOLR_TIP/$2" ]]; then
+ SOLR_SERVER_DIR="$SOLR_TIP/$2"
+ else
+ SOLR_SERVER_DIR="$2"
+ fi
+ fi
+ # resolve it to an absolute path
+ SOLR_SERVER_DIR="$(cd "$SOLR_SERVER_DIR"; pwd)"
+ shift 2
+ ;;
+ -s|-solr.home)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Solr home directory is required when using the $1 option!"
+ exit 1
+ fi
+
+ SOLR_HOME="$2"
+ shift 2
+ ;;
+ -t|-data.home)
+ SOLR_DATA_HOME="$2"
+ shift 2
+ ;;
+ -e|-example)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Example name is required when using the $1 option!"
+ exit 1
+ fi
+ EXAMPLE="$2"
+ shift 2
+ ;;
+ -f|-foreground)
+ FG="true"
+ shift
+ ;;
+ -h|-host)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Hostname is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_HOST="$2"
+ PASS_TO_RUN_EXAMPLE+=" -h $SOLR_HOST"
+ shift 2
+ ;;
+ -m|-memory)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Memory setting is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_HEAP="$2"
+ PASS_TO_RUN_EXAMPLE+=" -m $SOLR_HEAP"
+ shift 2
+ ;;
+ -p|-port)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Port number is required when using the $1 option!"
+ exit 1
+ fi
+ SOLR_PORT="$2"
+ PASS_TO_RUN_EXAMPLE+=" -p $SOLR_PORT"
+ shift 2
+ ;;
+ -z|-zkhost)
+ if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+ print_usage "$SCRIPT_CMD" "Zookeeper connection string is required when using the $1 option!"
+ exit 1
+ fi
+ ZK_HOST="$2"
+ SOLR_MODE="solrcloud"
+ PASS_TO_RUN_EXAMPLE+=" -z $ZK_HOST"
+ shift 2
+ ;;
+ -a|-addlopts)
+ ADDITIONAL_CMD_OPTS="$2"
+ PASS_TO_RUN_EXAMPLE+=" -a \"$ADDITIONAL_CMD_OPTS\""
+ shift 2
+ ;;
+ -j|-jettyconfig)
+ ADDITIONAL_JETTY_CONFIG="$2"
+ PASS_TO_RUN_EXAMPLE+=" -j \"$ADDITIONAL_JETTY_CONFIG\""
+ shift 2
+ ;;
+ -k|-key)
+ STOP_KEY="$2"
+ shift 2
+ ;;
+ -help|-usage)
+ print_usage "$SCRIPT_CMD"
+ exit 0
+ ;;
+ -noprompt)
+ noprompt=true
+ PASS_TO_RUN_EXAMPLE+=" -noprompt"
+ shift
+ ;;
+ -V|-verbose)
+ verbose=true
+ PASS_TO_RUN_EXAMPLE+=" --verbose"
+ shift
+ ;;
+ -v)
+ SOLR_LOG_LEVEL=DEBUG
+ shift
+ ;;
+ -q)
+ SOLR_LOG_LEVEL=WARN
+ shift
+ ;;
+ -all)
+ stop_all=true
+ shift
+ ;;
+ -force)
+ FORCE=true
+ PASS_TO_RUN_EXAMPLE+=" -force"
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ if [ "${1:0:2}" == "-D" ]; then
+ # pass thru any opts that begin with -D (java system props)
+ SOLR_OPTS+=("$1")
+ PASS_TO_RUN_EXAMPLE+=" $1"
+ shift
+ else
+ if [ "$1" != "" ]; then
+ print_usage "$SCRIPT_CMD" "$1 is not supported by this script"
+ exit 1
+ else
+ break # out-of-args, stop looping
+ fi
+ fi
+ ;;
+ esac
+ done
+fi
+
+if [[ $SOLR_LOG_LEVEL ]] ; then
+ SOLR_LOG_LEVEL_OPT="-Dsolr.log.level=$SOLR_LOG_LEVEL"
+fi
+
+if [ -z "$SOLR_SERVER_DIR" ]; then
+ SOLR_SERVER_DIR="$DEFAULT_SERVER_DIR"
+fi
+
+if [ ! -e "$SOLR_SERVER_DIR" ]; then
+ echo -e "\nSolr server directory $SOLR_SERVER_DIR not found!\n"
+ exit 1
+fi
+
+if [[ "$FG" == 'true' && "$EXAMPLE" != "" ]]; then
+ FG='false'
+ echo -e "\nWARNING: Foreground mode (-f) not supported when running examples.\n"
+fi
+
+#
+# If the user specified an example to run, invoke the run_example tool (Java app) and exit
+# otherwise let this script proceed to process the user request
+#
+if [ -n "$EXAMPLE" ] && [ "$SCRIPT_CMD" == "start" ]; then
+ run_tool run_example -e $EXAMPLE -d "$SOLR_SERVER_DIR" -urlScheme $SOLR_URL_SCHEME $PASS_TO_RUN_EXAMPLE
+ exit $?
+fi
+
+############# start/stop logic below here ################
+
+if $verbose ; then
+ echo "Using Solr root directory: $SOLR_TIP"
+ echo "Using Java: $JAVA"
+ "$JAVA" -version
+fi
+
+if [ "$SOLR_HOST" != "" ]; then
+ SOLR_HOST_ARG=("-Dhost=$SOLR_HOST")
+else
+ SOLR_HOST_ARG=()
+fi
+
+if [ -z "$STOP_KEY" ]; then
+ STOP_KEY='solrrocks'
+fi
+
+# stop all if no port specified
+if [[ "$SCRIPT_CMD" == "stop" && -z "$SOLR_PORT" ]]; then
+ if $stop_all; then
+ none_stopped=true
+ find "$SOLR_PID_DIR" -name "solr-*.pid" -type f | while read PIDF
+ do
+ NEXT_PID=`cat "$PIDF"`
+ port=`jetty_port "$NEXT_PID"`
+ if [ "$port" != "" ]; then
+ stop_solr "$SOLR_SERVER_DIR" "$port" "$STOP_KEY" "$NEXT_PID"
+ none_stopped=false
+ fi
+ rm -f "$PIDF"
+ done
+ # TODO: none_stopped doesn't get reflected across the subshell
+ # This can be uncommented once we find a clean way out of it
+ # if $none_stopped; then
+ # echo -e "\nNo Solr nodes found to stop.\n"
+ # fi
+ else
+ # not stopping all and don't have a port, but if we can find the pid file for the default port 8983, then use that
+ none_stopped=true
+ numSolrs=`find "$SOLR_PID_DIR" -name "solr-*.pid" -type f | wc -l | tr -d ' '`
+ if [ $numSolrs -eq 1 ]; then
+ # only do this if there is only 1 node running, otherwise they must provide the -p or -all
+ PID="$(cat "$(find "$SOLR_PID_DIR" -name "solr-*.pid" -type f)")"
+ CHECK_PID=`ps auxww | awk '{print $2}' | grep -w $PID | sort -r | tr -d ' '`
+ if [ "$CHECK_PID" != "" ]; then
+ port=`jetty_port "$CHECK_PID"`
+ if [ "$port" != "" ]; then
+ stop_solr "$SOLR_SERVER_DIR" "$port" "$STOP_KEY" "$CHECK_PID"
+ none_stopped=false
+ fi
+ fi
+ fi
+
+ if $none_stopped; then
+ if [ $numSolrs -gt 0 ]; then
+ echo -e "\nFound $numSolrs Solr nodes running! Must either specify a port using -p or -all to stop all Solr nodes on this host.\n"
+ else
+ echo -e "\nNo Solr nodes found to stop.\n"
+ fi
+ exit 1
+ fi
+ fi
+ exit
+fi
+
+if [ -z "$SOLR_PORT" ]; then
+ SOLR_PORT=8983
+fi
+
+if [ -z "$STOP_PORT" ]; then
+ STOP_PORT=`expr $SOLR_PORT - 1000`
+fi
+
+if [ "$SCRIPT_CMD" == "start" ] || [ "$SCRIPT_CMD" == "restart" ] ; then
+ if [[ "$(whoami)" == "root" ]] && [[ "$FORCE" == "false" ]] ; then
+ echo "WARNING: Starting Solr as the root user is a security risk and not considered best practice. Exiting."
+ echo " Please consult the Reference Guide. To override this check, start with argument '-force'"
+ exit 1
+ fi
+fi
+
+if [[ "$SCRIPT_CMD" == "start" ]]; then
+ # see if Solr is already running
+ SOLR_PID=`solr_pid_by_port "$SOLR_PORT"`
+
+ if [ -z "$SOLR_PID" ]; then
+ # not found using the pid file ... but use ps to ensure not found
+ SOLR_PID=`ps auxww | grep start\.jar | grep -w "\-Djetty\.port=$SOLR_PORT" | grep -v grep | awk '{print $2}' | sort -r`
+ fi
+
+ if [ "$SOLR_PID" != "" ]; then
+ echo -e "\nPort $SOLR_PORT is already being used by another process (pid: $SOLR_PID)\nPlease choose a different port using the -p option.\n"
+ exit 1
+ fi
+else
+ # either stop or restart
+ # see if Solr is already running
+ SOLR_PID=`solr_pid_by_port "$SOLR_PORT"`
+ if [ -z "$SOLR_PID" ]; then
+ # not found using the pid file ... but use ps to ensure not found
+ SOLR_PID=`ps auxww | grep start\.jar | grep -w "\-Djetty\.port=$SOLR_PORT" | grep -v grep | awk '{print $2}' | sort -r`
+ fi
+ if [ "$SOLR_PID" != "" ]; then
+ stop_solr "$SOLR_SERVER_DIR" "$SOLR_PORT" "$STOP_KEY" "$SOLR_PID"
+ else
+ if [ "$SCRIPT_CMD" == "stop" ]; then
+ echo -e "No process found for Solr node running on port $SOLR_PORT"
+ exit 1
+ fi
+ fi
+fi
+
+if [ -z "$SOLR_HOME" ]; then
+ SOLR_HOME="$SOLR_SERVER_DIR/solr"
+elif [[ $SOLR_HOME != /* ]]; then
+ if [[ -d "`pwd`/$SOLR_HOME" ]]; then
+ SOLR_HOME="$(pwd)/$SOLR_HOME"
+ elif [[ -d "$SOLR_SERVER_DIR/$SOLR_HOME" ]]; then
+ SOLR_HOME="$SOLR_SERVER_DIR/$SOLR_HOME"
+ SOLR_PID_DIR="$SOLR_HOME"
+ fi
+fi
+
+# Set the default configset dir to be bootstrapped as _default
+if [ -z "$DEFAULT_CONFDIR" ]; then
+ DEFAULT_CONFDIR="$SOLR_SERVER_DIR/solr/configsets/_default/conf"
+fi
+
+# This is quite hacky, but examples rely on a different log4j2.xml
+# so that we can write logs for examples to $SOLR_HOME/../logs
+if [ -z "$SOLR_LOGS_DIR" ]; then
+ SOLR_LOGS_DIR="$SOLR_SERVER_DIR/logs"
+fi
+EXAMPLE_DIR="$SOLR_TIP/example"
+if [ "${SOLR_HOME:0:${#EXAMPLE_DIR}}" = "$EXAMPLE_DIR" ]; then
+ LOG4J_PROPS="$DEFAULT_SERVER_DIR/resources/log4j2.xml"
+ SOLR_LOGS_DIR="$SOLR_HOME/../logs"
+fi
+
+LOG4J_CONFIG=()
+if [ -n "$LOG4J_PROPS" ]; then
+ LOG4J_CONFIG+=("-Dlog4j.configurationFile=file:$LOG4J_PROPS")
+fi
+
+if [ "$SCRIPT_CMD" == "stop" ]; then
+ # already stopped, script is done.
+ exit 0
+fi
+
+# NOTE: If the script gets to here, then it is starting up a Solr node.
+
+if [ ! -e "$SOLR_HOME" ]; then
+ echo -e "\nSolr home directory $SOLR_HOME not found!\n"
+ exit 1
+fi
+if [[ $SOLR_DATA_HOME ]] && [ ! -e "$SOLR_DATA_HOME" ]; then
+ echo -e "\nSolr data home directory $SOLR_DATA_HOME not found!\n"
+ exit 1
+fi
+if $verbose ; then
+ q=""
+else
+ q="-q"
+fi
+# Rotate and clean on startup. Default to false since 7.4 as log4j2 handles startup rotation
+if [ "${SOLR_LOG_PRESTART_ROTATION:=false}" == "true" ]; then
+ # Enable any of these if you require old remove/archive behavior
+ #run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" $q -remove_old_solr_logs 7 || echo "Failed removing old solr logs"
+ #run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" $q -archive_gc_logs $q || echo "Failed archiving old GC logs"
+ #run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" $q -archive_console_logs || echo "Failed archiving old console logs"
+ run_tool utils -s "$DEFAULT_SERVER_DIR" -l "$SOLR_LOGS_DIR" $q -rotate_solr_logs 10 || echo "Failed rotating old solr logs"
+fi
+
+# Establish default GC logging opts if no env var set (otherwise init to sensible default)
+if [ -z ${GC_LOG_OPTS+x} ]; then
+ if [[ "$JAVA_VER_NUM" -lt "9" ]] ; then
+ GC_LOG_OPTS=('-verbose:gc' '-XX:+PrintHeapAtGC' '-XX:+PrintGCDetails' \
+ '-XX:+PrintGCDateStamps' '-XX:+PrintGCTimeStamps' '-XX:+PrintTenuringDistribution' \
+ '-XX:+PrintGCApplicationStoppedTime')
+ else
+ GC_LOG_OPTS=('-Xlog:gc*')
+ fi
+else
+ GC_LOG_OPTS=($GC_LOG_OPTS)
+fi
+
+# if verbose gc logging enabled, setup the location of the log file and rotation
+if [ "$GC_LOG_OPTS" != "" ]; then
+ if [[ "$JAVA_VER_NUM" -lt "9" ]] ; then
+ gc_log_flag="-Xloggc"
+ if [ "$JAVA_VENDOR" == "IBM J9" ]; then
+ gc_log_flag="-Xverbosegclog"
+ fi
+ GC_LOG_OPTS+=("$gc_log_flag:$SOLR_LOGS_DIR/solr_gc.log" '-XX:+UseGCLogFileRotation' '-XX:NumberOfGCLogFiles=9' '-XX:GCLogFileSize=20M')
+ else
+ # http://openjdk.java.net/jeps/158
+ for i in "${!GC_LOG_OPTS[@]}";
+ do
+ # for simplicity, we only look at the prefix '-Xlog:gc'
+ # (if 'all' or multiple tags are used starting with anything other then 'gc' the user is on their own)
+ # if a single additional ':' exists in param, then there is already an explicit output specifier
+ GC_LOG_OPTS[$i]=$(echo ${GC_LOG_OPTS[$i]} | sed "s|^\(-Xlog:gc[^:]*$\)|\1:file=$SOLR_LOGS_DIR/solr_gc.log:time,uptime:filecount=9,filesize=20M|")
+ done
+ fi
+fi
+
+# If ZK_HOST is defined, the assume SolrCloud mode
+if [[ -n "$ZK_HOST" ]]; then
+ SOLR_MODE="solrcloud"
+fi
+
+if [ "$SOLR_MODE" == 'solrcloud' ]; then
+ if [ -z "$ZK_CLIENT_TIMEOUT" ]; then
+ ZK_CLIENT_TIMEOUT="15000"
+ fi
+
+ CLOUD_MODE_OPTS=("-DzkClientTimeout=$ZK_CLIENT_TIMEOUT")
+
+ if [ "$ZK_HOST" != "" ]; then
+ CLOUD_MODE_OPTS+=("-DzkHost=$ZK_HOST")
+ else
+ if $verbose ; then
+ echo "Configuring SolrCloud to launch an embedded Zookeeper using -DzkRun"
+ fi
+
+ CLOUD_MODE_OPTS+=('-DzkRun')
+ fi
+
+ # and if collection1 needs to be bootstrapped
+ if [ -e "$SOLR_HOME/collection1/core.properties" ]; then
+ CLOUD_MODE_OPTS+=('-Dbootstrap_confdir=./solr/collection1/conf' '-Dcollection.configName=myconf' '-DnumShards=1')
+ fi
+
+else
+ if [ ! -e "$SOLR_HOME/solr.xml" ]; then
+ echo -e "\nSolr home directory $SOLR_HOME must contain a solr.xml file!\n"
+ exit 1
+ fi
+fi
+
+# These are useful for attaching remote profilers like VisualVM/JConsole
+if [ "$ENABLE_REMOTE_JMX_OPTS" == "true" ]; then
+
+ if [ -z "$RMI_PORT" ]; then
+ RMI_PORT=`expr $SOLR_PORT + 10000`
+ if [ $RMI_PORT -gt 65535 ]; then
+ echo -e "\nRMI_PORT is $RMI_PORT, which is invalid!\n"
+ exit 1
+ fi
+ fi
+
+ REMOTE_JMX_OPTS=('-Dcom.sun.management.jmxremote' \
+ '-Dcom.sun.management.jmxremote.local.only=false' \
+ '-Dcom.sun.management.jmxremote.ssl=false' \
+ '-Dcom.sun.management.jmxremote.authenticate=false' \
+ "-Dcom.sun.management.jmxremote.port=$RMI_PORT" \
+ "-Dcom.sun.management.jmxremote.rmi.port=$RMI_PORT")
+
+ # if the host is set, then set that as the rmi server hostname
+ if [ "$SOLR_HOST" != "" ]; then
+ REMOTE_JMX_OPTS+=("-Djava.rmi.server.hostname=$SOLR_HOST")
+ fi
+else
+ REMOTE_JMX_OPTS=()
+fi
+
+JAVA_MEM_OPTS=()
+if [ -z "$SOLR_HEAP" ] && [ -n "$SOLR_JAVA_MEM" ]; then
+ JAVA_MEM_OPTS=($SOLR_JAVA_MEM)
+else
+ SOLR_HEAP="${SOLR_HEAP:-512m}"
+ JAVA_MEM_OPTS=("-Xms$SOLR_HEAP" "-Xmx$SOLR_HEAP")
+fi
+
+# Pick default for Java thread stack size, and then add to SOLR_OPTS
+if [ -z ${SOLR_JAVA_STACK_SIZE+x} ]; then
+ SOLR_JAVA_STACK_SIZE='-Xss256k'
+fi
+SOLR_OPTS+=($SOLR_JAVA_STACK_SIZE)
+
+if [ -z "$SOLR_TIMEZONE" ]; then
+ SOLR_TIMEZONE='UTC'
+fi
+
+# Launches Solr in foreground/background depending on parameters
+function start_solr() {
+
+ run_in_foreground="$1"
+ stop_port="$STOP_PORT"
+
+ SOLR_ADDL_ARGS="$2"
+ SOLR_JETTY_ADDL_CONFIG="$3"
+
+ # define default GC_TUNE
+ if [ -z ${GC_TUNE+x} ]; then
+ GC_TUNE=('-XX:+UseG1GC' \
+ '-XX:+PerfDisableSharedMem' \
+ '-XX:+ParallelRefProcEnabled' \
+ '-XX:MaxGCPauseMillis=250' \
+ '-XX:+UseLargePages' \
+ '-XX:+AlwaysPreTouch')
+ else
+ GC_TUNE=($GC_TUNE)
+ fi
+
+ if [ -n "$SOLR_WAIT_FOR_ZK" ]; then
+ WAIT_FOR_ZK_PROP="-DwaitForZk=$SOLR_WAIT_FOR_ZK"
+ SOLR_OPTS+=($WAIT_FOR_ZK_PROP)
+ fi
+
+ # If SSL-related system props are set, add them to SOLR_OPTS
+ if [ "$SOLR_SSL_ENABLED" ]; then
+ # If using SSL and solr.jetty.https.port not set explicitly, use the jetty.port
+ SSL_PORT_PROP="-Dsolr.jetty.https.port=$SOLR_PORT"
+ SOLR_OPTS+=($SOLR_SSL_OPTS "$SSL_PORT_PROP")
+ fi
+
+ # If authentication system props are set, add them to SOLR_OPTS
+ if [ -n "$AUTHC_OPTS" ]; then
+ SOLR_OPTS+=($AUTHC_OPTS)
+ fi
+
+ if $verbose ; then
+ echo -e "\nStarting Solr using the following settings:"
+ echo -e " JAVA = $JAVA"
+ echo -e " SOLR_SERVER_DIR = $SOLR_SERVER_DIR"
+ echo -e " SOLR_HOME = $SOLR_HOME"
+ echo -e " SOLR_HOST = $SOLR_HOST"
+ echo -e " SOLR_PORT = $SOLR_PORT"
+ echo -e " STOP_PORT = $STOP_PORT"
+ echo -e " JAVA_MEM_OPTS = ${JAVA_MEM_OPTS[@]}"
+ echo -e " GC_TUNE = ${GC_TUNE[@]}"
+ echo -e " GC_LOG_OPTS = ${GC_LOG_OPTS[@]}"
+ echo -e " SOLR_TIMEZONE = $SOLR_TIMEZONE"
+
+ if [ "$SOLR_MODE" == "solrcloud" ]; then
+ echo -e " CLOUD_MODE_OPTS = ${CLOUD_MODE_OPTS[@]}"
+ fi
+
+ if [ "$SOLR_OPTS" != "" ]; then
+ echo -e " SOLR_OPTS = ${SOLR_OPTS[@]}"
+ fi
+
+ if [ "$SOLR_ADDL_ARGS" != "" ]; then
+ echo -e " SOLR_ADDL_ARGS = $SOLR_ADDL_ARGS"
+ fi
+
+ if [ "$ENABLE_REMOTE_JMX_OPTS" == "true" ]; then
+ echo -e " RMI_PORT = $RMI_PORT"
+ echo -e " REMOTE_JMX_OPTS = ${REMOTE_JMX_OPTS[@]}"
+ fi
+
+ if [ "$SOLR_LOG_LEVEL" != "" ]; then
+ echo -e " SOLR_LOG_LEVEL = $SOLR_LOG_LEVEL"
+ fi
+
+ if [ "$SOLR_DATA_HOME" != "" ]; then
+ echo -e " SOLR_DATA_HOME = $SOLR_DATA_HOME"
+ fi
+ echo -e "\n"
+ fi
+
+ # need to launch solr from the server dir
+ cd "$SOLR_SERVER_DIR"
+
+ if [ ! -e "$SOLR_SERVER_DIR/start.jar" ]; then
+ echo -e "\nERROR: start.jar file not found in $SOLR_SERVER_DIR!\nPlease check your -d parameter to set the correct Solr server directory.\n"
+ exit 1
+ fi
+
+ SOLR_START_OPTS=('-server' "${JAVA_MEM_OPTS[@]}" "${GC_TUNE[@]}" "${GC_LOG_OPTS[@]}" \
+ "${REMOTE_JMX_OPTS[@]}" "${CLOUD_MODE_OPTS[@]}" $SOLR_LOG_LEVEL_OPT -Dsolr.log.dir="$SOLR_LOGS_DIR" \
+ "-Djetty.port=$SOLR_PORT" "-DSTOP.PORT=$stop_port" "-DSTOP.KEY=$STOP_KEY" \
+ "${SOLR_HOST_ARG[@]}" "-Duser.timezone=$SOLR_TIMEZONE" \
+ "-Djetty.home=$SOLR_SERVER_DIR" "-Dsolr.solr.home=$SOLR_HOME" "-Dsolr.data.home=$SOLR_DATA_HOME" "-Dsolr.install.dir=$SOLR_TIP" \
+ "-Dsolr.default.confdir=$DEFAULT_CONFDIR" "${LOG4J_CONFIG[@]}" "${SOLR_OPTS[@]}")
+
+ if [ "$SOLR_MODE" == "solrcloud" ]; then
+ IN_CLOUD_MODE=" in SolrCloud mode"
+ fi
+
+ mkdir -p "$SOLR_LOGS_DIR" 2>/dev/null
+ if [ $? -ne 0 ]; then
+ echo -e "\nERROR: Logs directory $SOLR_LOGS_DIR could not be created. Exiting"
+ exit 1
+ fi
+ if [ ! -w "$SOLR_LOGS_DIR" ]; then
+ echo -e "\nERROR: Logs directory $SOLR_LOGS_DIR is not writable. Exiting"
+ exit 1
+ fi
+ case "$SOLR_LOGS_DIR" in
+ contexts|etc|lib|modules|resources|scripts|solr|solr-webapp)
+ echo -e "\nERROR: Logs directory $SOLR_LOGS_DIR is invalid. Reserved for the system. Exiting"
+ exit 1
+ ;;
+ esac
+
+ if [ "$run_in_foreground" == "true" ]; then
+ exec "$JAVA" "${SOLR_START_OPTS[@]}" $SOLR_ADDL_ARGS -jar start.jar "${SOLR_JETTY_CONFIG[@]}" $SOLR_JETTY_ADDL_CONFIG
+ else
+ # run Solr in the background
+ nohup "$JAVA" "${SOLR_START_OPTS[@]}" $SOLR_ADDL_ARGS -Dsolr.log.muteconsole \
+ "-XX:OnOutOfMemoryError=$SOLR_TIP/bin/oom_solr.sh $SOLR_PORT $SOLR_LOGS_DIR" \
+ -jar start.jar "${SOLR_JETTY_CONFIG[@]}" $SOLR_JETTY_ADDL_CONFIG \
+ 1>"$SOLR_LOGS_DIR/solr-$SOLR_PORT-console.log" 2>&1 & echo $! > "$SOLR_PID_DIR/solr-$SOLR_PORT.pid"
+
+ # check if /proc/sys/kernel/random/entropy_avail exists then check output of cat /proc/sys/kernel/random/entropy_avail to see if less than 300
+ if [[ -f /proc/sys/kernel/random/entropy_avail ]] && (( `cat /proc/sys/kernel/random/entropy_avail` < 300)); then
+ echo "Warning: Available entropy is low. As a result, use of the UUIDField, SSL, or any other features that require"
+ echo "RNG might not work properly. To check for the amount of available entropy, use 'cat /proc/sys/kernel/random/entropy_avail'."
+ echo ""
+ fi
+ # no lsof on cygwin though
+ if hash lsof 2>/dev/null ; then # hash returns true if lsof is on the path
+ echo -n "Waiting up to $SOLR_STOP_WAIT seconds to see Solr running on port $SOLR_PORT"
+ # Launch in a subshell to show the spinner
+ (loops=0
+ while true
+ do
+ running=`lsof -PniTCP:$SOLR_PORT -sTCP:LISTEN`
+ if [ -z "$running" ]; then
+ slept=$((loops * 2))
+ if [ $slept -lt $SOLR_STOP_WAIT ]; then
+ sleep 2
+ loops=$[$loops+1]
+ else
+ echo -e "Still not seeing Solr listening on $SOLR_PORT after $SOLR_STOP_WAIT seconds!"
+ tail -30 "$SOLR_LOGS_DIR/solr.log"
+ exit # subshell!
+ fi
+ else
+ SOLR_PID=`ps auxww | grep start\.jar | grep -w "\-Djetty\.port=$SOLR_PORT" | grep -v grep | awk '{print $2}' | sort -r`
+ echo -e "\nStarted Solr server on port $SOLR_PORT (pid=$SOLR_PID). Happy searching!\n"
+ exit # subshell!
+ fi
+ done) &
+ spinner $!
+ else
+ echo -e "NOTE: Please install lsof as this script needs it to determine if Solr is listening on port $SOLR_PORT."
+ sleep 10
+ SOLR_PID=`ps auxww | grep start\.jar | grep -w "\-Djetty\.port=$SOLR_PORT" | grep -v grep | awk '{print $2}' | sort -r`
+ echo -e "\nStarted Solr server on port $SOLR_PORT (pid=$SOLR_PID). Happy searching!\n"
+ return;
+ fi
+ fi
+}
+
+start_solr "$FG" "$ADDITIONAL_CMD_OPTS" "$ADDITIONAL_JETTY_CONFIG"
+
+exit $?
diff --git a/KeywordSearch/solr/bin/solr.cmd b/KeywordSearch/solr/bin/solr.cmd
new file mode 100755
index 0000000000..40bf81e05a
--- /dev/null
+++ b/KeywordSearch/solr/bin/solr.cmd
@@ -0,0 +1,2031 @@
+set JAVA_HOME=C:\Program Files\ojdkbuild\java-1.8.0-openjdk-1.8.0.222-1
+set SOLR_SERVER_DIR=C:\Bitnami\solr-8.2.0-2/apache-solr/server
+set SOLR_PORT=8983
+set STOP_PORT=8079
+
+@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one or more
+@REM contributor license agreements. See the NOTICE file distributed with
+@REM this work for additional information regarding copyright ownership.
+@REM The ASF licenses this file to You under the Apache License, Version 2.0
+@REM (the "License"); you may not use this file except in compliance with
+@REM the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing, software
+@REM distributed under the License is distributed on an "AS IS" BASIS,
+@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@REM See the License for the specific language governing permissions and
+@REM limitations under the License.
+
+@echo off
+
+IF "%OS%"=="Windows_NT" setlocal enabledelayedexpansion enableextensions
+
+set "PASS_TO_RUN_EXAMPLE="
+
+REM Determine top-level Solr directory
+set SDIR=%~dp0
+IF "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1%
+set SOLR_TIP=%SDIR%\..
+pushd %SOLR_TIP%
+set SOLR_TIP=%CD%
+popd
+
+REM Used to report errors before exiting the script
+set SCRIPT_ERROR=
+set NO_USER_PROMPT=0
+
+REM Allow user to import vars from an include file
+REM vars set in the include file can be overridden with
+REM command line args
+IF "%SOLR_INCLUDE%"=="" set "SOLR_INCLUDE=%SOLR_TIP%\bin\solr.in.cmd"
+IF EXIST "%SOLR_INCLUDE%" CALL "%SOLR_INCLUDE%"
+
+set "DEFAULT_SERVER_DIR=%SOLR_TIP%\server"
+
+REM Select HTTP OR HTTPS related configurations
+set SOLR_URL_SCHEME=http
+set "SOLR_JETTY_CONFIG=--module=http"
+set "SOLR_SSL_OPTS= "
+
+IF DEFINED SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dhadoop.security.credential.provider.path=%SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH%"
+)
+
+IF NOT DEFINED SOLR_SSL_ENABLED (
+ IF DEFINED SOLR_SSL_KEY_STORE (
+ set "SOLR_SSL_ENABLED=true"
+ ) ELSE (
+ set "SOLR_SSL_ENABLED=false"
+ )
+)
+
+IF "%SOLR_SSL_ENABLED%"=="true" (
+ set "SOLR_JETTY_CONFIG=--lib="%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*""
+ if !JAVA_MAJOR_VERSION! GEQ 9 (
+ set "SOLR_JETTY_CONFIG=!SOLR_JETTY_CONFIG! --module=https"
+ ) else (
+ set "SOLR_JETTY_CONFIG=!SOLR_JETTY_CONFIG! --module=https8"
+ )
+ set SOLR_URL_SCHEME=https
+ IF DEFINED SOLR_SSL_KEY_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%"
+ )
+
+ IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.type=%SOLR_SSL_KEY_STORE_TYPE%"
+ )
+
+ IF DEFINED SOLR_SSL_TRUST_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore=%SOLR_SSL_TRUST_STORE%"
+ )
+ IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.type=%SOLR_SSL_TRUST_STORE_TYPE%"
+ )
+
+ IF DEFINED SOLR_SSL_NEED_CLIENT_AUTH (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.ssl.needClientAuth=%SOLR_SSL_NEED_CLIENT_AUTH%"
+ )
+ IF DEFINED SOLR_SSL_WANT_CLIENT_AUTH (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.ssl.wantClientAuth=%SOLR_SSL_WANT_CLIENT_AUTH%"
+ )
+
+ IF DEFINED SOLR_SSL_CLIENT_KEY_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_CLIENT_KEY_STORE%"
+
+ IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_CLIENT_KEY_STORE_TYPE%"
+ )
+ ) ELSE (
+ IF DEFINED SOLR_SSL_KEY_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_KEY_STORE%"
+ )
+ IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_KEY_STORE_TYPE%"
+ )
+ )
+
+ IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_CLIENT_TRUST_STORE%"
+
+ IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_CLIENT_TRUST_STORE_TYPE%"
+ )
+ ) ELSE (
+ IF DEFINED SOLR_SSL_TRUST_STORE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_TRUST_STORE%"
+ )
+ IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_TRUST_STORE_TYPE%"
+ )
+ )
+ IF DEFINED SOLR_SSL_CHECK_PEER_NAME (
+ set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.ssl.checkPeerName=%SOLR_SSL_CHECK_PEER_NAME%"
+ )
+) ELSE (
+ set SOLR_SSL_OPTS=
+)
+
+REM Authentication options
+
+IF NOT DEFINED SOLR_AUTH_TYPE (
+ IF DEFINED SOLR_AUTHENTICATION_OPTS (
+ echo WARNING: SOLR_AUTHENTICATION_OPTS variable configured without associated SOLR_AUTH_TYPE variable
+ echo Please configure SOLR_AUTH_TYPE variable with the authentication type to be used.
+ echo Currently supported authentication types are [kerberos, basic]
+ )
+)
+
+IF DEFINED SOLR_AUTH_TYPE (
+ IF DEFINED SOLR_AUTHENTICATION_CLIENT_BUILDER (
+ echo WARNING: SOLR_AUTHENTICATION_CLIENT_BUILDER and SOLR_AUTH_TYPE variables are configured together
+ echo Use SOLR_AUTH_TYPE variable to configure authentication type to be used
+ echo Currently supported authentication types are [kerberos, basic]
+ echo The value of SOLR_AUTHENTICATION_CLIENT_BUILDER configuration variable will be ignored
+ )
+)
+
+IF DEFINED SOLR_AUTH_TYPE (
+ IF /I "%SOLR_AUTH_TYPE%" == "basic" (
+ set SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"
+ ) ELSE (
+ IF /I "%SOLR_AUTH_TYPE%" == "kerberos" (
+ set SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"
+ ) ELSE (
+ echo ERROR: Value specified for SOLR_AUTH_TYPE configuration variable is invalid.
+ goto err
+ )
+ )
+)
+
+IF DEFINED SOLR_AUTHENTICATION_CLIENT_CONFIGURER (
+ echo WARNING: Found unsupported configuration variable SOLR_AUTHENTICATION_CLIENT_CONFIGURER
+ echo Please start using SOLR_AUTH_TYPE instead
+)
+IF DEFINED SOLR_AUTHENTICATION_CLIENT_BUILDER (
+ set AUTHC_CLIENT_BUILDER_ARG="-Dsolr.httpclient.builder.factory=%SOLR_AUTHENTICATION_CLIENT_BUILDER%"
+)
+set "AUTHC_OPTS=%AUTHC_CLIENT_BUILDER_ARG% %SOLR_AUTHENTICATION_OPTS%"
+
+REM Set the SOLR_TOOL_HOST variable for use when connecting to a running Solr instance
+IF NOT "%SOLR_HOST%"=="" (
+ set "SOLR_TOOL_HOST=%SOLR_HOST%"
+) ELSE (
+ set "SOLR_TOOL_HOST=localhost"
+)
+IF "%SOLR_JETTY_HOST%"=="" (
+ set SOLR_JETTY_HOST=0.0.0.0
+)
+
+REM Verify Java is available
+IF DEFINED SOLR_JAVA_HOME set "JAVA_HOME=%SOLR_JAVA_HOME%"
+REM Try to detect JAVA_HOME from the registry
+IF NOT DEFINED JAVA_HOME (
+ FOR /F "skip=2 tokens=2*" %%A IN ('REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment" /v CurrentVersion') DO set CurVer=%%B
+ FOR /F "skip=2 tokens=2*" %%A IN ('REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment\!CurVer!" /v JavaHome') DO (
+ set "JAVA_HOME=%%B"
+ )
+)
+IF NOT DEFINED JAVA_HOME goto need_java_home
+set JAVA_HOME=%JAVA_HOME:"=%
+IF %JAVA_HOME:~-1%==\ SET JAVA_HOME=%JAVA_HOME:~0,-1%
+IF NOT EXIST "%JAVA_HOME%\bin\java.exe" (
+ set "SCRIPT_ERROR=java.exe not found in %JAVA_HOME%\bin. Please set JAVA_HOME to a valid JRE / JDK directory."
+ goto err
+)
+set "JAVA=%JAVA_HOME%\bin\java"
+CALL :resolve_java_info
+IF !JAVA_MAJOR_VERSION! LSS 8 (
+ set "SCRIPT_ERROR=Java 1.8 or later is required to run Solr. Current Java version is: !JAVA_VERSION_INFO! (detected major: !JAVA_MAJOR_VERSION!)"
+ goto err
+)
+
+set FIRST_ARG=%1
+
+IF [%1]==[] goto usage
+
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="-h" goto usage
+IF "%1"=="--help" goto usage
+IF "%1"=="/?" goto usage
+IF "%1"=="-i" goto get_info
+IF "%1"=="-info" goto get_info
+IF "%1"=="status" goto get_info
+IF "%1"=="version" goto get_version
+IF "%1"=="-v" goto get_version
+IF "%1"=="-version" goto get_version
+IF "%1"=="assert" goto run_assert
+IF "%1"=="autoscaling" goto run_autoscaling
+
+REM Only allow the command to be the first argument, assume start if not supplied
+IF "%1"=="start" goto set_script_cmd
+IF "%1"=="stop" goto set_script_cmd
+IF "%1"=="restart" goto set_script_cmd
+IF "%1"=="healthcheck" (
+ REM healthcheck uses different arg parsing strategy
+ set SCRIPT_CMD=healthcheck
+ SHIFT
+ goto parse_healthcheck_args
+)
+IF "%1"=="create" (
+ set SCRIPT_CMD=create
+ SHIFT
+ goto parse_create_args
+)
+IF "%1"=="create_core" (
+ set SCRIPT_CMD=create_core
+ SHIFT
+ goto parse_create_args
+)
+IF "%1"=="create_collection" (
+ set SCRIPT_CMD=create_collection
+ SHIFT
+ goto parse_create_args
+)
+IF "%1"=="delete" (
+ set SCRIPT_CMD=delete
+ SHIFT
+ goto parse_delete_args
+)
+IF "%1"=="zk" (
+ set SCRIPT_CMD=zk
+ SHIFT
+ set ZK_RECURSE=false
+ goto parse_zk_args
+)
+IF "%1"=="auth" (
+ set SCRIPT_CMD=auth
+ SHIFT
+ goto run_auth
+)
+IF "%1"=="config" (
+ REM config uses different arg parsing strategy
+ set SCRIPT_CMD=config
+ SHIFT
+ set CONFIG_ARGS=
+ goto parse_config_args
+)
+
+goto parse_args
+
+:usage
+IF NOT "%SCRIPT_ERROR%"=="" ECHO %SCRIPT_ERROR%
+IF [%FIRST_ARG%]==[] goto script_usage
+IF "%FIRST_ARG%"=="-help" goto script_usage
+IF "%FIRST_ARG%"=="-usage" goto script_usage
+IF "%FIRST_ARG%"=="-h" goto script_usage
+IF "%FIRST_ARG%"=="--help" goto script_usage
+IF "%FIRST_ARG%"=="/?" goto script_usage
+IF "%SCRIPT_CMD%"=="start" goto start_usage
+IF "%SCRIPT_CMD%"=="restart" goto start_usage
+IF "%SCRIPT_CMD%"=="stop" goto stop_usage
+IF "%SCRIPT_CMD%"=="healthcheck" goto healthcheck_usage
+IF "%SCRIPT_CMD%"=="create" goto create_usage
+IF "%SCRIPT_CMD%"=="create_core" goto create_core_usage
+IF "%SCRIPT_CMD%"=="create_collection" goto create_collection_usage
+IF "%SCRIPT_CMD%"=="delete" goto delete_usage
+IF "%SCRIPT_CMD%"=="zk" goto zk_usage
+IF "%SCRIPT_CMD%"=="auth" goto auth_usage
+IF "%SCRIPT_CMD%"=="status" goto status_usage
+goto done
+
+:script_usage
+@echo.
+@echo Usage: solr COMMAND OPTIONS
+@echo where COMMAND is one of: start, stop, restart, healthcheck, create, create_core, create_collection, delete, version, zk, auth, assert, config, autoscaling
+@echo.
+@echo Standalone server example (start Solr running in the background on port 8984):
+@echo.
+@echo solr start -p 8984
+@echo.
+@echo SolrCloud example (start Solr running in SolrCloud mode using localhost:2181 to connect to Zookeeper, with 1g max heap size and remote Java debug options enabled):
+@echo.
+@echo solr start -c -m 1g -z localhost:2181 -a "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044"
+@echo.
+@echo Omit '-z localhost:2181' from the above command if you have defined ZK_HOST in solr.in.cmd.
+@echo.
+@echo Pass -help after any COMMAND to see command-specific usage information,
+@echo such as: solr start -help or solr stop -help
+@echo.
+goto done
+
+:start_usage
+@echo.
+@echo Usage: solr %SCRIPT_CMD% [-f] [-c] [-h hostname] [-p port] [-d directory] [-z zkHost] [-m memory] [-e example] [-s solr.solr.home] [-t solr.data.home] [-a "additional-options"] [-V]
+@echo.
+@echo -f Start Solr in foreground; default starts Solr in the background
+@echo and sends stdout / stderr to solr-PORT-console.log
+@echo.
+@echo -c or -cloud Start Solr in SolrCloud mode; if -z not supplied and ZK_HOST not defined in
+@echo solr.in.cmd, an embedded ZooKeeper instance is started on Solr port+1000,
+@echo such as 9983 if Solr is bound to 8983
+@echo.
+@echo -h host Specify the hostname for this Solr instance
+@echo.
+@echo -p port Specify the port to start the Solr HTTP listener on; default is 8983
+@echo " The specified port (SOLR_PORT) will also be used to determine the stop port"
+@echo " STOP_PORT=(\$SOLR_PORT-1000) and JMX RMI listen port RMI_PORT=(\$SOLR_PORT+10000). "
+@echo " For instance, if you set -p 8985, then the STOP_PORT=7985 and RMI_PORT=18985"
+@echo.
+@echo -d dir Specify the Solr server directory; defaults to server
+@echo.
+@echo -z zkHost Zookeeper connection string; only used when running in SolrCloud mode using -c
+@echo If neither ZK_HOST is defined in solr.in.cmd nor the -z parameter is specified,
+@echo an embedded ZooKeeper instance will be launched.
+@echo.
+@echo -m memory Sets the min (-Xms) and max (-Xmx) heap size for the JVM, such as: -m 4g
+@echo results in: -Xms4g -Xmx4g; by default, this script sets the heap size to 512m
+@echo.
+@echo -s dir Sets the solr.solr.home system property; Solr will create core directories under
+@echo this directory. This allows you to run multiple Solr instances on the same host
+@echo while reusing the same server directory set using the -d parameter. If set, the
+@echo specified directory should contain a solr.xml file, unless solr.xml exists in Zookeeper.
+@echo This parameter is ignored when running examples (-e), as the solr.solr.home depends
+@echo on which example is run. The default value is server/solr. If passed a relative dir
+@echo validation with the current dir will be done before trying the default server/^
+@echo.
+@echo -t dir Sets the solr.data.home system property, where Solr will store index data in ^/data subdirectories.
+@echo If not set, Solr uses solr.solr.home for both config and data.
+@echo.
+@echo -e example Name of the example to run; available examples:
+@echo cloud: SolrCloud example
+@echo techproducts: Comprehensive example illustrating many of Solr's core capabilities
+@echo dih: Data Import Handler
+@echo schemaless: Schema-less example
+@echo.
+@echo -a opts Additional parameters to pass to the JVM when starting Solr, such as to setup
+@echo Java debug options. For example, to enable a Java debugger to attach to the Solr JVM
+@echo you could pass: -a "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=18983"
+@echo In most cases, you should wrap the additional parameters in double quotes.
+@echo.
+@echo -j opts Additional parameters to pass to Jetty when starting Solr.
+@echo For example, to add configuration folder that jetty should read
+@echo you could pass: -j "--include-jetty-dir=/etc/jetty/custom/server/"
+@echo In most cases, you should wrap the additional parameters in double quotes.
+@echo.
+@echo -noprompt Don't prompt for input; accept all defaults when running examples that accept user input
+@echo.
+@echo -v and -q Verbose (-v) or quiet (-q) logging. Sets default log level to DEBUG or WARN instead of INFO
+@echo.
+@echo -V/-verbose Verbose messages from this script
+@echo.
+goto done
+
+:status_usage
+@echo.
+@echo Usage: solr status
+@echo.
+@echo NOTE: This command will show the status of all running Solr servers
+@echo.
+goto done
+
+:stop_usage
+@echo.
+@echo Usage: solr stop [-k key] [-p port] [-V]
+@echo.
+@echo -k key Stop key; default is solrrocks
+@echo.
+@echo -p port Specify the port the Solr HTTP listener is bound to
+@echo.
+@echo -all Find and stop all running Solr servers on this host
+@echo.
+@echo -V/-verbose Verbose messages from this script
+@echo.
+@echo NOTE: To see if any Solr servers are running, do: solr status
+@echo.
+goto done
+
+:healthcheck_usage
+@echo.
+@echo Usage: solr healthcheck [-c collection] [-z zkHost] [-V]
+@echo.
+@echo Can be run from remote (non-Solr^) hosts, as long as a proper ZooKeeper connection is provided
+@echo.
+@echo -c collection Collection to run healthcheck against.
+@echo.
+@echo -z zkHost Zookeeper connection string; unnecessary if ZK_HOST is defined in solr.in.cmd;
+@echo otherwise, default is localhost:9983
+@echo.
+@echo -V Enable more verbose output
+@echo.
+goto done
+
+:create_usage
+echo.
+echo Usage: solr create [-c name] [-d confdir] [-n confname] [-shards #] [-replicationFactor #] [-p port] [-V]
+echo.
+echo Create a core or collection depending on whether Solr is running in standalone (core) or SolrCloud
+echo mode (collection). In other words, this action detects which mode Solr is running in, and then takes
+echo the appropriate action (either create_core or create_collection). For detailed usage instructions, do:
+echo.
+echo bin\solr create_core -help
+echo.
+echo or
+echo.
+echo bin\solr create_collection -help
+echo.
+goto done
+
+:delete_usage
+echo.
+echo Usage: solr delete [-c name] [-deleteConfig true^|false] [-p port] [-V]
+echo.
+echo Deletes a core or collection depending on whether Solr is running in standalone (core) or SolrCloud
+echo mode (collection). If you're deleting a collection in SolrCloud mode, the default behavior is to also
+echo delete the configuration directory from Zookeeper so long as it is not being used by another collection.
+echo You can override this behavior by passing -deleteConfig false when running this command.
+echo.
+echo Can be run on remote (non-Solr^) hosts, as long as a valid SOLR_HOST is provided in solr.in.cmd
+echo.
+echo -c name Name of core to delete
+echo.
+echo -deleteConfig boolean Delete the configuration directory from Zookeeper; default is true
+echo.
+echo -p port Port of a local Solr instance where you want to delete the core/collection
+echo If not specified, the script will search the local system for a running
+echo Solr instance and will use the port of the first server it finds.
+echo.
+echo -V Enables more verbose output.
+echo.
+goto done
+
+:create_core_usage
+echo.
+echo Usage: solr create_core [-c ^] [-d confdir] [-p port] [-V]
+echo.
+echo When a configSet is used, this can be run from any host. If pointing at a non-configSet directory, this
+echo must be run from the host that you wish to create the core on.
+echo.
+echo -c ^ Name of core to create
+echo.
+echo -d confdir Configuration directory to copy when creating the new core, built-in options are:
+echo.
+echo _default: Minimal configuration, which supports enabling/disabling field-guessing support
+echo sample_techproducts_configs: Example configuration with many optional features enabled to
+echo demonstrate the full power of Solr
+echo.
+echo If not specified, default is: _default
+echo.
+echo Alternatively, you can pass the path to your own configuration directory instead of using
+echo one of the built-in configurations, such as: bin\solr create_core -c mycore -d c:/tmp/myconfig
+echo.
+echo -p port Port of a local Solr instance where you want to create the new core
+echo If not specified, the script will search the local system for a running
+echo Solr instance and will use the port of the first server it finds.
+echo.
+echo -V Enable more verbose output.
+echo.
+goto done
+
+:create_collection_usage
+echo.
+echo Usage: solr create_collection [-c collection] [-d confdir] [-n confname] [-shards #] [-replicationFactor #] [-p port] [-V]
+echo.
+echo Can be run from remote (non-Solr^) hosts, as long as a valid SOLR_HOST is provided in solr.in.cmd.
+echo.
+echo -c ^ Name of collection to create
+echo.
+echo -d ^ Configuration directory to copy when creating the new collection, built-in options are:
+echo.
+echo _default: Minimal configuration, which supports enabling/disabling field-guessing support
+echo sample_techproducts_configs: Example configuration with many optional features enabled to
+echo demonstrate the full power of Solr
+echo.
+echo If not specified, default is: _default
+echo.
+echo Alternatively, you can pass the path to your own configuration directory instead of using
+echo one of the built-in configurations, such as: bin\solr create_collection -c mycoll -d c:/tmp/myconfig
+echo.
+echo By default the script will upload the specified confdir directory into Zookeeper using the same
+echo name as the collection (-c) option. Alternatively, if you want to reuse an existing directory
+echo or create a confdir in Zookeeper that can be shared by multiple collections, use the -n option
+echo.
+echo -n configName Name the configuration directory in Zookeeper; by default, the configuration
+echo will be uploaded to Zookeeper using the collection name (-c), but if you want
+echo to use an existing directory or override the name of the configuration in
+echo Zookeeper, then use the -c option.
+echo.
+echo -shards # Number of shards to split the collection into; default is 1
+echo.
+echo -replicationFactor # Number of copies of each document in the collection, default is 1 (no replication)
+echo.
+echo -p port Port of a local Solr instance where you want to create the new collection
+echo If not specified, the script will search the local system for a running
+echo Solr instance and will use the port of the first server it finds.
+echo.
+echo -V Enable more verbose output.
+echo.
+goto done
+
+:zk_usage
+set ZK_FULL=true
+goto zk_short_usage
+:zk_full_usage
+echo Can be run on remote (non-Solr^) hosts, as long as valid ZK_HOST information is provided.
+echo Be sure to check the Solr logs in case of errors.
+echo.
+echo -z zkHost Optional Zookeeper connection string for all commands. If specified it
+echo overrides the 'ZK_HOST=...'' defined in solr.in.cmd.
+echo.
+echo -V Enable more verbose output.
+echo.
+echo upconfig uploads a configset from the local machine to Zookeeper. (Backcompat: -upconfig)
+echo.
+echo downconfig downloads a configset from Zookeeper to the local machine. (Backcompat: -downconfig)
+echo.
+echo -n configName Name of the configset in Zookeeper that will be the destination of
+echo 'upconfig' and the source for 'downconfig'.
+echo.
+echo -d confdir The local directory the configuration will be uploaded from for
+echo 'upconfig' or downloaded to for 'downconfig'. If 'confdir' is a child of
+echo ...solr/server/solr/configsets' then the configs will be copied from/to
+echo that directory. Otherwise it is interpreted as a simple local path.
+echo.
+echo cp copies files or folders to/from Zookeeper or Zokeeper -^> Zookeeper
+echo -r Recursively copy ^ to ^. Command will fail if ^ has children and
+echo -r is not specified. Optional
+echo.
+echo. ^, ^ : [file:][/]path/to/local/file or zk:/path/to/zk/node
+echo NOTE: ^ and ^ may both be Zookeeper resources prefixed by 'zk:'
+echo When ^ is a zk resource, ^ may be '.'
+echo If ^ ends with '/', then ^ will be a local folder or parent znode and the last
+echo element of the ^ path will be appended unless ^ also ends in a slash.
+echo ^ may be zk:, which may be useful when using the cp -r form to backup/restore
+echo the entire zk state.
+echo You must enclose local paths that end in a wildcard in quotes or just
+echo end the local path in a slash. That is,
+echo 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181' is equivalent to
+echo 'bin/solr zk cp -r ^"/some/dir/*^" zk:/ -z localhost:2181'
+echo but 'bin/solr zk cp -r /some/dir/* zk:/ -z localhost:2181' will throw an error.
+echo.
+echo Here's an example of backup/restore for a ZK configuration:
+echo to copy to local: 'bin/solr zk cp -r zk:/ /some/dir -z localhost:2181'
+echo to restore to ZK: 'bin/solr zk cp -r /some/dir/ zk:/ -z localhost:2181'
+echo.
+echo The 'file:' prefix is stripped, thus 'file:/wherever' specifies an absolute local path and
+echo 'file:somewhere' specifies a relative local path. All paths on Zookeeper are absolute.
+echo.
+echo Zookeeper nodes CAN have data, so moving a single file to a parent znode
+echo will overlay the data on the parent Znode so specifying the trailing slash
+echo can be important.
+echo.
+echo Wildcards are supported when copying from local, trailing only and must be quoted.
+echo.
+echo rm deletes files or folders on Zookeeper
+echo -r Recursively delete if ^ is a directory. Command will fail if ^
+echo has children and -r is not specified. Optional
+echo ^ : [zk:]/path/to/zk/node. ^ may not be the root ('/')
+echo.
+echo mv moves (renames) znodes on Zookeeper
+echo ^, ^ : Zookeeper nodes, the 'zk:' prefix is optional.
+echo If ^ ends with '/', then ^ will be a parent znode
+echo and the last element of the ^ path will be appended.
+echo Zookeeper nodes CAN have data, so moving a single file to a parent znode
+echo will overlay the data on the parent Znode so specifying the trailing slash
+echo is important.
+echo.
+echo ls lists the znodes on Zookeeper
+echo -r recursively descends the path listing all znodes. Optional
+echo ^: The Zookeeper path to use as the root.
+echo.
+echo Only the node names are listed, not data
+echo.
+echo mkroot makes a znode in Zookeeper with no data. Can be used to make a path of arbitrary
+echo depth but primarily intended to create a 'chroot'.
+echo.
+echo ^: The Zookeeper path to create. Leading slash is assumed if not present.
+echo Intermediate nodes are created as needed if not present.
+echo.
+
+goto done
+
+:zk_short_usage
+IF NOT "!ERROR_MSG!"=="" (
+ echo ERROR: !ERROR_MSG!
+ echo.
+)
+echo Usage: solr zk upconfig^|downconfig -d ^ -n ^ [-z zkHost]
+echo solr zk cp [-r] ^ ^ [-z zkHost]
+echo solr zk rm [-r] ^ [-z zkHost]
+echo solr zk mv ^ ^ [-z zkHost]
+echo solr zk ls [-r] ^ [-z zkHost]
+echo solr zk mkroot ^ [-z zkHost]
+echo.
+IF "%ZK_FULL%"=="true" (
+ goto zk_full_usage
+) ELSE (
+ echo Type bin/solr zk -help for full usage help
+)
+goto done
+
+:auth_usage
+echo Usage: solr auth enable [-type basicAuth] -credentials user:pass [-blockUnknown ^] [-updateIncludeFileOnly ^] [-V]
+echo solr auth enable [-type basicAuth] -prompt ^ [-blockUnknown ^] [-updateIncludeFileOnly ^] [-V]
+echo solr auth disable [-updateIncludeFileOnly ^] [-V]
+echo.
+echo Updates or enables/disables authentication. Must be run on the machine hosting Solr.
+echo.
+echo -type ^ The authentication mechanism to enable. Defaults to 'basicAuth'.
+echo.
+echo -credentials ^ The username and password of the initial user
+echo Note: only one of -prompt or -credentials must be provided
+echo.
+echo -prompt ^ Prompts the user to provide the credentials
+echo Note: only one of -prompt or -credentials must be provided
+echo.
+echo -blockUnknown ^ When true, this blocks out access to unauthenticated users. When not provided,
+echo this defaults to false (i.e. unauthenticated users can access all endpoints, except the
+echo operations like collection-edit, security-edit, core-admin-edit etc.^). Check the reference
+echo guide for Basic Authentication for more details.
+echo.
+echo -updateIncludeFileOnly ^ Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
+echo authentication (i.e. don't update security.json^)"
+echo.
+echo -z zkHost Zookeeper connection string. Unnecessary if ZK_HOST is defined in solr.in.cmd.
+echo.
+echo -d ^ Specify the Solr server directory"
+echo.
+echo -s ^ Specify the Solr home directory. This is where any credentials or authentication"
+echo configuration files (e.g. basicAuth.conf^) would be placed."
+echo.
+echo -V Enable more verbose output
+echo.
+goto done
+
+REM Really basic command-line arg parsing
+:parse_args
+
+set "arg=%~1"
+set "firstTwo=%arg:~0,2%"
+IF "%SCRIPT_CMD%"=="" set SCRIPT_CMD=start
+IF [%1]==[] goto process_script_cmd
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+IF "%1"=="-f" goto set_foreground_mode
+IF "%1"=="-foreground" goto set_foreground_mode
+IF "%1"=="-V" goto set_verbose
+IF "%1"=="-verbose" goto set_verbose
+IF "%1"=="-v" goto set_debug
+IF "%1"=="-q" goto set_warn
+IF "%1"=="-c" goto set_cloud_mode
+IF "%1"=="-cloud" goto set_cloud_mode
+IF "%1"=="-d" goto set_server_dir
+IF "%1"=="-dir" goto set_server_dir
+IF "%1"=="-s" goto set_solr_home_dir
+IF "%1"=="-t" goto set_solr_data_dir
+IF "%1"=="-solr.home" goto set_solr_home_dir
+IF "%1"=="-e" goto set_example
+IF "%1"=="-example" goto set_example
+IF "%1"=="-h" goto set_host
+IF "%1"=="-host" goto set_host
+IF "%1"=="-m" goto set_memory
+IF "%1"=="-memory" goto set_memory
+IF "%1"=="-p" goto set_port
+IF "%1"=="-port" goto set_port
+IF "%1"=="-z" goto set_zookeeper
+IF "%1"=="-zkhost" goto set_zookeeper
+IF "%1"=="-zkHost" goto set_zookeeper
+IF "%1"=="-a" goto set_addl_opts
+IF "%1"=="-addlopts" goto set_addl_opts
+IF "%1"=="-j" goto set_addl_jetty_config
+IF "%1"=="-jettyconfig" goto set_addl_jetty_config
+IF "%1"=="-noprompt" goto set_noprompt
+IF "%1"=="-k" goto set_stop_key
+IF "%1"=="-key" goto set_stop_key
+IF "%1"=="-all" goto set_stop_all
+IF "%firstTwo%"=="-D" goto set_passthru
+IF NOT "%1"=="" goto invalid_cmd_line
+goto invalid_cmd_line
+
+:set_script_cmd
+set SCRIPT_CMD=%1
+SHIFT
+goto parse_args
+
+:set_foreground_mode
+set FG=1
+SHIFT
+goto parse_args
+
+:set_verbose
+set verbose=1
+set "PASS_TO_RUN_EXAMPLE=--verbose !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+goto parse_args
+
+:set_debug
+set SOLR_LOG_LEVEL=DEBUG
+SHIFT
+goto parse_args
+
+:set_warn
+set SOLR_LOG_LEVEL=WARN
+SHIFT
+goto parse_args
+
+:set_cloud_mode
+set SOLR_MODE=solrcloud
+SHIFT
+goto parse_args
+
+:set_server_dir
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Directory name is required!
+ goto invalid_cmd_line
+)
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected directory but found %2 instead!
+ goto invalid_cmd_line
+)
+
+REM See if they are using a short-hand name relative from the Solr tip directory
+IF EXIST "%SOLR_TIP%\%~2" (
+ set "SOLR_SERVER_DIR=%SOLR_TIP%\%~2"
+) ELSE (
+ set "SOLR_SERVER_DIR=%~2"
+)
+SHIFT
+SHIFT
+goto parse_args
+
+:set_solr_home_dir
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Directory name is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected directory but found %2 instead!
+ goto invalid_cmd_line
+)
+set "SOLR_HOME=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_solr_data_dir
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Directory name is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected directory but found %2 instead!
+ goto invalid_cmd_line
+)
+set "SOLR_DATA_HOME=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_example
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Example name is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected example name but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set EXAMPLE=%~2
+SHIFT
+SHIFT
+goto parse_args
+
+:set_memory
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Memory setting is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected memory setting but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set SOLR_HEAP=%~2
+set "PASS_TO_RUN_EXAMPLE=-m %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_host
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Hostname is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected hostname but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set SOLR_HOST=%~2
+set "PASS_TO_RUN_EXAMPLE=-h %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_port
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Port is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected port but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set SOLR_PORT=%~2
+set "PASS_TO_RUN_EXAMPLE=-p %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_stop_key
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Stop key is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected stop key but found %2 instead!
+ goto invalid_cmd_line
+)
+set STOP_KEY=%~2
+SHIFT
+SHIFT
+goto parse_args
+
+:set_stop_all
+set STOP_ALL=1
+SHIFT
+goto parse_args
+
+:set_zookeeper
+
+set "arg=%~2"
+IF "%arg%"=="" (
+ set SCRIPT_ERROR=Zookeeper connection string is required!
+ goto invalid_cmd_line
+)
+
+set firstChar=%arg:~0,1%
+IF "%firstChar%"=="-" (
+ set SCRIPT_ERROR=Expected Zookeeper connection string but found %2 instead!
+ goto invalid_cmd_line
+)
+
+set "ZK_HOST=%~2"
+set "PASS_TO_RUN_EXAMPLE=-z %~2 !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_addl_opts
+set "arg=%~2"
+set "SOLR_ADDL_ARGS=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_addl_jetty_config
+set "arg=%~2"
+set "SOLR_JETTY_ADDL_CONFIG=%~2"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_passthru
+set "PASSTHRU=%~1=%~2"
+IF NOT "%SOLR_OPTS%"=="" (
+ set "SOLR_OPTS=%SOLR_OPTS% %PASSTHRU%"
+) ELSE (
+ set "SOLR_OPTS=%PASSTHRU%"
+)
+set "PASS_TO_RUN_EXAMPLE=%PASSTHRU% !PASS_TO_RUN_EXAMPLE!"
+SHIFT
+SHIFT
+goto parse_args
+
+:set_noprompt
+set NO_USER_PROMPT=1
+set "PASS_TO_RUN_EXAMPLE=-noprompt !PASS_TO_RUN_EXAMPLE!"
+
+SHIFT
+goto parse_args
+
+REM Perform the requested command after processing args
+:process_script_cmd
+
+IF "%verbose%"=="1" (
+ CALL :safe_echo "Using Solr root directory: %SOLR_TIP%"
+ CALL :safe_echo "Using Java: %JAVA%"
+ "%JAVA%" -version
+ @echo.
+)
+
+IF NOT "%SOLR_HOST%"=="" (
+ set SOLR_HOST_ARG=-Dhost=%SOLR_HOST%
+) ELSE (
+ set SOLR_HOST_ARG=
+)
+
+IF "%SOLR_SERVER_DIR%"=="" set "SOLR_SERVER_DIR=%DEFAULT_SERVER_DIR%"
+
+IF NOT EXIST "%SOLR_SERVER_DIR%" (
+ set "SCRIPT_ERROR=Solr server directory %SOLR_SERVER_DIR% not found!"
+ goto err
+)
+
+IF NOT "%EXAMPLE%"=="" goto run_example
+
+:start_solr
+IF "%SOLR_HOME%"=="" set "SOLR_HOME=%SOLR_SERVER_DIR%\solr"
+IF EXIST "%cd%\%SOLR_HOME%" set "SOLR_HOME=%cd%\%SOLR_HOME%"
+
+IF NOT EXIST "%SOLR_HOME%\" (
+ IF EXIST "%SOLR_SERVER_DIR%\%SOLR_HOME%" (
+ set "SOLR_HOME=%SOLR_SERVER_DIR%\%SOLR_HOME%"
+ ) ELSE (
+ set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% not found!"
+ goto err
+ )
+)
+
+IF "%STOP_KEY%"=="" set STOP_KEY=solrrocks
+
+@REM This is quite hacky, but examples rely on a different log4j2.xml
+@REM so that we can write logs for examples to %SOLR_HOME%\..\logs
+IF [%SOLR_LOGS_DIR%] == [] (
+ set "SOLR_LOGS_DIR=%SOLR_SERVER_DIR%\logs"
+) ELSE (
+ set SOLR_LOGS_DIR=%SOLR_LOGS_DIR:"=%
+)
+
+set "EXAMPLE_DIR=%SOLR_TIP%\example"
+set TMP_SOLR_HOME=!SOLR_HOME:%EXAMPLE_DIR%=!
+IF NOT "%TMP_SOLR_HOME%"=="%SOLR_HOME%" (
+ set "SOLR_LOGS_DIR=%SOLR_HOME%\..\logs"
+ set "LOG4J_CONFIG=file:///%SOLR_SERVER_DIR%\resources\log4j2.xml"
+)
+
+set IS_RESTART=0
+IF "%SCRIPT_CMD%"=="restart" (
+ IF "%SOLR_PORT%"=="" (
+ set "SCRIPT_ERROR=Must specify the port when trying to restart Solr."
+ goto err
+ )
+ set SCRIPT_CMD=stop
+ set IS_RESTART=1
+)
+
+@REM stop logic here
+IF "%SCRIPT_CMD%"=="stop" (
+ IF "%SOLR_PORT%"=="" (
+ IF "%STOP_ALL%"=="1" (
+ set found_it=0
+ for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ @REM j is the ip:port and k is the pid
+ IF NOT "%%k"=="0" (
+ IF "%%j"=="%SOLR_JETTY_HOST%:!SOME_SOLR_PORT!" (
+ set found_it=1
+ @echo Stopping Solr process %%k running on port !SOME_SOLR_PORT!
+ IF "%STOP_PORT%"=="" set /A STOP_PORT=!SOME_SOLR_PORT! - 1000
+ "%JAVA%" %SOLR_SSL_OPTS% -Djetty.home="%SOLR_SERVER_DIR%" -jar "%SOLR_SERVER_DIR%\start.jar" STOP.PORT=!STOP_PORT! STOP.KEY=%STOP_KEY% --stop
+ del "%SOLR_TIP%"\bin\solr-!SOME_SOLR_PORT!.port
+ timeout /T 5
+ REM Kill it if it is still running after the graceful shutdown
+ For /f "tokens=2,5" %%M in ('netstat -nao ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF "%%N"=="%%k" (
+ IF "%%M"=="%SOLR_JETTY_HOST%:!SOME_SOLR_PORT!" (
+ @echo Forcefully killing process %%N
+ taskkill /f /PID %%N
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ if "!found_it!"=="0" echo No Solr nodes found to stop.
+ ) ELSE (
+ set "SCRIPT_ERROR=Must specify the port when trying to stop Solr, or use -all to stop all running nodes on this host."
+ goto err
+ )
+ ) ELSE (
+ set found_it=0
+ For /f "tokens=2,5" %%M in ('netstat -nao ^| find "TCP " ^| find ":0 " ^| find ":%SOLR_PORT% "') do (
+ IF NOT "%%N"=="0" (
+ IF "%%M"=="%SOLR_JETTY_HOST%:%SOLR_PORT%" (
+ set found_it=1
+ @echo Stopping Solr process %%N running on port %SOLR_PORT%
+ IF "%STOP_PORT%"=="" set /A STOP_PORT=%SOLR_PORT% - 1000
+ "%JAVA%" %SOLR_SSL_OPTS% -Djetty.home="%SOLR_SERVER_DIR%" -jar "%SOLR_SERVER_DIR%\start.jar" %SOLR_JETTY_CONFIG% STOP.PORT=!STOP_PORT! STOP.KEY=%STOP_KEY% --stop
+ del "%SOLR_TIP%"\bin\solr-%SOLR_PORT%.port
+ timeout /T 5
+ REM Kill it if it is still running after the graceful shutdown
+ For /f "tokens=2,5" %%j in ('netstat -nao ^| find "TCP " ^| find ":0 " ^| find ":%SOLR_PORT% "') do (
+ IF "%%N"=="%%k" (
+ IF "%%j"=="%SOLR_JETTY_HOST%:%SOLR_PORT%" (
+ @echo Forcefully killing process %%N
+ taskkill /f /PID %%N
+ )
+ )
+ )
+ )
+ )
+ )
+ if "!found_it!"=="0" echo No Solr found running on port %SOLR_PORT%
+ )
+
+ IF "!IS_RESTART!"=="0" goto done
+)
+
+IF "!IS_RESTART!"=="1" set SCRIPT_CMD=start
+
+IF "%SOLR_PORT%"=="" set SOLR_PORT=8983
+IF "%STOP_PORT%"=="" set /A STOP_PORT=%SOLR_PORT% - 1000
+
+IF "%SCRIPT_CMD%"=="start" (
+ REM see if Solr is already running using netstat
+ For /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":%SOLR_PORT% "') do (
+ IF NOT "%%k"=="0" (
+ IF "%%j"=="%SOLR_JETTY_HOST%:%SOLR_PORT%" (
+ set "SCRIPT_ERROR=Process %%k is already listening on port %SOLR_PORT%. If this is Solr, please stop it first before starting (or use restart). If this is not Solr, then please choose a different port using -p PORT"
+ goto err
+ )
+ )
+ )
+)
+
+@REM determine if -server flag is supported by current JVM
+"%JAVA%" -server -version > nul 2>&1
+IF ERRORLEVEL 1 (
+ set IS_JDK=false
+ set "SERVEROPT="
+ @echo WARNING: You are using a JRE without support for -server option. Please upgrade to latest JDK for best performance
+ @echo.
+) ELSE (
+ set IS_JDK=true
+ set "SERVEROPT=-server"
+)
+if !JAVA_MAJOR_VERSION! LSS 9 (
+ "%JAVA%" -d64 -version > nul 2>&1
+ IF ERRORLEVEL 1 (
+ set "IS_64BIT=false"
+ @echo WARNING: 32-bit Java detected. Not recommended for production. Point your JAVA_HOME to a 64-bit JDK
+ @echo.
+ ) ELSE (
+ set IS_64bit=true
+ )
+) ELSE (
+ set IS_64bit=true
+)
+
+REM Clean up and rotate logs. Default to false since 7.4 as log4j2 handles startup rotation
+IF [%SOLR_LOG_PRESTART_ROTATION%] == [] (
+ set SOLR_LOG_PRESTART_ROTATION=false
+)
+IF [%SOLR_LOG_PRESTART_ROTATION%] == [true] (
+ REM Enable any of these if you require old remove/archive behavior
+ REM call :run_utils "-remove_old_solr_logs 7" || echo "Failed removing old solr logs"
+ REM call :run_utils "-archive_gc_logs" || echo "Failed archiving old GC logs"
+ REM call :run_utils "-archive_console_logs" || echo "Failed archiving old console logs"
+ call :run_utils "-rotate_solr_logs 9" || echo "Failed rotating old solr logs"
+)
+
+IF NOT "%ZK_HOST%"=="" set SOLR_MODE=solrcloud
+
+IF "%SOLR_MODE%"=="solrcloud" (
+ IF "%ZK_CLIENT_TIMEOUT%"=="" set "ZK_CLIENT_TIMEOUT=15000"
+
+ set "CLOUD_MODE_OPTS=-DzkClientTimeout=!ZK_CLIENT_TIMEOUT!"
+
+ IF NOT "%ZK_HOST%"=="" (
+ set "CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -DzkHost=%ZK_HOST%"
+ ) ELSE (
+ IF "%verbose%"=="1" echo Configuring SolrCloud to launch an embedded Zookeeper using -DzkRun
+ set "CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -DzkRun"
+ )
+ IF EXIST "%SOLR_HOME%\collection1\core.properties" set "CLOUD_MODE_OPTS=!CLOUD_MODE_OPTS! -Dbootstrap_confdir=./solr/collection1/conf -Dcollection.configName=myconf -DnumShards=1"
+) ELSE (
+ set CLOUD_MODE_OPTS=
+ IF NOT EXIST "%SOLR_HOME%\solr.xml" (
+ set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% must contain solr.xml!"
+ goto err
+ )
+)
+
+REM These are useful for attaching remove profilers like VisualVM/JConsole
+IF "%ENABLE_REMOTE_JMX_OPTS%"=="true" (
+ IF "!RMI_PORT!"=="" set RMI_PORT=1%SOLR_PORT%
+ set REMOTE_JMX_OPTS=-Dcom.sun.management.jmxremote ^
+-Dcom.sun.management.jmxremote.local.only=false ^
+-Dcom.sun.management.jmxremote.ssl=false ^
+-Dcom.sun.management.jmxremote.authenticate=false ^
+-Dcom.sun.management.jmxremote.port=!RMI_PORT! ^
+-Dcom.sun.management.jmxremote.rmi.port=!RMI_PORT!
+
+ IF NOT "%SOLR_HOST%"=="" set REMOTE_JMX_OPTS=%REMOTE_JMX_OPTS% -Djava.rmi.server.hostname=%SOLR_HOST%
+) ELSE (
+ set REMOTE_JMX_OPTS=
+)
+
+IF NOT "%SOLR_HEAP%"=="" set SOLR_JAVA_MEM=-Xms%SOLR_HEAP% -Xmx%SOLR_HEAP%
+IF "%SOLR_JAVA_MEM%"=="" set SOLR_JAVA_MEM=-Xms512m -Xmx512m
+IF "%SOLR_JAVA_STACK_SIZE%"=="" set SOLR_JAVA_STACK_SIZE=-Xss256k
+set SOLR_OPTS=%SOLR_JAVA_STACK_SIZE% %SOLR_OPTS%
+IF "%SOLR_TIMEZONE%"=="" set SOLR_TIMEZONE=UTC
+
+IF "%GC_TUNE%"=="" (
+ set GC_TUNE=-XX:+UseG1GC ^
+ -XX:+PerfDisableSharedMem ^
+ -XX:+ParallelRefProcEnabled ^
+ -XX:MaxGCPauseMillis=250 ^
+ -XX:+UseLargePages ^
+ -XX:+AlwaysPreTouch
+)
+
+if !JAVA_MAJOR_VERSION! GEQ 9 (
+ IF NOT "%GC_LOG_OPTS%"=="" (
+ echo ERROR: On Java 9 you cannot set GC_LOG_OPTS, only default GC logging is available. Exiting
+ GOTO :eof
+ )
+ set GC_LOG_OPTS="-Xlog:gc*:file=\"!SOLR_LOGS_DIR!\solr_gc.log\":time,uptime:filecount=9,filesize=20M"
+) else (
+ IF "%GC_LOG_OPTS%"=="" (
+ rem Set defaults for Java 8
+ set GC_LOG_OPTS=-verbose:gc ^
+ -XX:+PrintHeapAtGC ^
+ -XX:+PrintGCDetails ^
+ -XX:+PrintGCDateStamps ^
+ -XX:+PrintGCTimeStamps ^
+ -XX:+PrintTenuringDistribution ^
+ -XX:+PrintGCApplicationStoppedTime
+ )
+ if "%JAVA_VENDOR%" == "IBM J9" (
+ set GC_LOG_OPTS=!GC_LOG_OPTS! "-Xverbosegclog:!SOLR_LOGS_DIR!\solr_gc.log" -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=9 -XX:GCLogFileSize=20M
+ ) else (
+ set GC_LOG_OPTS=!GC_LOG_OPTS! "-Xloggc:!SOLR_LOGS_DIR!\solr_gc.log" -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=9 -XX:GCLogFileSize=20M
+ )
+)
+
+IF "%verbose%"=="1" (
+ @echo Starting Solr using the following settings:
+ CALL :safe_echo " JAVA = %JAVA%"
+ CALL :safe_echo " SOLR_SERVER_DIR = %SOLR_SERVER_DIR%"
+ CALL :safe_echo " SOLR_HOME = %SOLR_HOME%"
+ @echo SOLR_HOST = %SOLR_HOST%
+ @echo SOLR_PORT = %SOLR_PORT%
+ @echo STOP_PORT = %STOP_PORT%
+ @echo SOLR_JAVA_MEM = %SOLR_JAVA_MEM%
+ @echo GC_TUNE = !GC_TUNE!
+ @echo GC_LOG_OPTS = %GC_LOG_OPTS%
+ @echo SOLR_TIMEZONE = %SOLR_TIMEZONE%
+
+ IF "%SOLR_MODE%"=="solrcloud" (
+ @echo CLOUD_MODE_OPTS = %CLOUD_MODE_OPTS%
+ )
+
+ IF NOT "%SOLR_OPTS%"=="" (
+ @echo SOLR_OPTS = %SOLR_OPTS%
+ )
+
+ IF NOT "%SOLR_ADDL_ARGS%"=="" (
+ CALL :safe_echo " SOLR_ADDL_ARGS = %SOLR_ADDL_ARGS%"
+ )
+
+ IF NOT "%SOLR_JETTY_ADDL_CONFIG%"=="" (
+ CALL :safe_echo " SOLR_JETTY_ADDL_CONFIG = %SOLR_JETTY_ADDL_CONFIG%"
+ )
+
+ IF "%ENABLE_REMOTE_JMX_OPTS%"=="true" (
+ @echo RMI_PORT = !RMI_PORT!
+ @echo REMOTE_JMX_OPTS = %REMOTE_JMX_OPTS%
+ )
+
+ IF NOT "%SOLR_LOG_LEVEL%"=="" (
+ @echo SOLR_LOG_LEVEL = !SOLR_LOG_LEVEL!
+ )
+
+ IF NOT "%SOLR_DATA_HOME%"=="" (
+ @echo SOLR_DATA_HOME = !SOLR_DATA_HOME!
+ )
+
+ @echo.
+)
+
+set START_OPTS=-Duser.timezone=%SOLR_TIMEZONE%
+set START_OPTS=%START_OPTS% !GC_TUNE! %GC_LOG_OPTS%
+IF NOT "!CLOUD_MODE_OPTS!"=="" set "START_OPTS=%START_OPTS% !CLOUD_MODE_OPTS!"
+IF NOT "%REMOTE_JMX_OPTS%"=="" set "START_OPTS=%START_OPTS% %REMOTE_JMX_OPTS%"
+IF NOT "%SOLR_ADDL_ARGS%"=="" set "START_OPTS=%START_OPTS% %SOLR_ADDL_ARGS%"
+IF NOT "%SOLR_HOST_ARG%"=="" set "START_OPTS=%START_OPTS% %SOLR_HOST_ARG%"
+IF NOT "%SOLR_OPTS%"=="" set "START_OPTS=%START_OPTS% %SOLR_OPTS%"
+IF "%SOLR_SSL_ENABLED%"=="true" (
+ set "SSL_PORT_PROP=-Dsolr.jetty.https.port=%SOLR_PORT%"
+ set "START_OPTS=%START_OPTS% %SOLR_SSL_OPTS% !SSL_PORT_PROP!"
+)
+IF NOT "%SOLR_LOG_LEVEL%"=="" set "START_OPTS=%START_OPTS% -Dsolr.log.level=%SOLR_LOG_LEVEL%"
+
+set SOLR_LOGS_DIR_QUOTED="%SOLR_LOGS_DIR%"
+set SOLR_DATA_HOME_QUOTED="%SOLR_DATA_HOME%"
+
+set "START_OPTS=%START_OPTS% -Dsolr.log.dir=%SOLR_LOGS_DIR_QUOTED%"
+IF NOT "%SOLR_DATA_HOME%"=="" set "START_OPTS=%START_OPTS% -Dsolr.data.home=%SOLR_DATA_HOME_QUOTED%"
+IF NOT DEFINED LOG4J_CONFIG set "LOG4J_CONFIG=file:///%SOLR_SERVER_DIR%\resources\log4j2.xml"
+
+cd /d "%SOLR_SERVER_DIR%"
+
+IF NOT EXIST "%SOLR_LOGS_DIR%" (
+ mkdir "%SOLR_LOGS_DIR%"
+)
+copy /Y NUL "%SOLR_LOGS_DIR%\.writable" > NUL 2>&1 && set WRITEOK=1
+IF DEFINED WRITEOK (
+ del "%SOLR_LOGS_DIR%\.writable"
+) else (
+ echo "ERROR: Logs directory %SOLR_LOGS_DIR% is not writable or could not be created. Exiting"
+ GOTO :eof
+)
+echo " contexts etc lib modules resources scripts solr solr-webapp " > "%TEMP%\solr-pattern.txt"
+findstr /i /C:" %SOLR_LOGS_DIR% " "%TEMP%\solr-pattern.txt" 1>nul
+if %ERRORLEVEL% == 0 (
+ echo "ERROR: Logs directory %SOLR_LOGS_DIR% is invalid. Reserved for the system. Exiting"
+ GOTO :eof
+)
+
+IF NOT EXIST "%SOLR_SERVER_DIR%\tmp" (
+ mkdir "%SOLR_SERVER_DIR%\tmp"
+)
+
+IF "%DEFAULT_CONFDIR%"=="" set "DEFAULT_CONFDIR=%SOLR_SERVER_DIR%\solr\configsets\_default\conf"
+
+IF "%FG%"=="1" (
+ REM run solr in the foreground
+ title "Solr-%SOLR_PORT%"
+ echo %SOLR_PORT%>"%SOLR_TIP%"\bin\solr-%SOLR_PORT%.port
+ "%JAVA%" %SERVEROPT% %SOLR_JAVA_MEM% %START_OPTS% ^
+ -Dlog4j.configurationFile="%LOG4J_CONFIG%" -DSTOP.PORT=!STOP_PORT! -DSTOP.KEY=%STOP_KEY% ^
+ -Dsolr.solr.home="%SOLR_HOME%" -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%" ^
+ -Djetty.host=%SOLR_JETTY_HOST% -Djetty.port=%SOLR_PORT% -Djetty.home="%SOLR_SERVER_DIR%" ^
+ -Djava.io.tmpdir="%SOLR_SERVER_DIR%\tmp" -jar start.jar %SOLR_JETTY_CONFIG% "%SOLR_JETTY_ADDL_CONFIG%"
+) ELSE (
+ START /B "Solr-%SOLR_PORT%" /D "%SOLR_SERVER_DIR%" ^
+ "%JAVA%" %SERVEROPT% %SOLR_JAVA_MEM% %START_OPTS% ^
+ -Dlog4j.configurationFile="%LOG4J_CONFIG%" -DSTOP.PORT=!STOP_PORT! -DSTOP.KEY=%STOP_KEY% ^
+ -Dsolr.log.muteconsole ^
+ -Dsolr.solr.home="%SOLR_HOME%" -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%" ^
+ -Djetty.host=%SOLR_JETTY_HOST% -Djetty.port=%SOLR_PORT% -Djetty.home="%SOLR_SERVER_DIR%" ^
+ -Djava.io.tmpdir="%SOLR_SERVER_DIR%\tmp" -jar start.jar %SOLR_JETTY_CONFIG% "%SOLR_JETTY_ADDL_CONFIG%" > "!SOLR_LOGS_DIR!\solr-%SOLR_PORT%-console.log"
+ echo %SOLR_PORT%>"%SOLR_TIP%"\bin\solr-%SOLR_PORT%.port
+
+ REM now wait to see Solr come online ...
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%"^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI status -maxWaitSecs 30 -solr !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:%SOLR_PORT%/solr
+)
+
+goto done
+
+:run_example
+REM Run the requested example
+
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI run_example -script "%SDIR%\solr.cmd" -e %EXAMPLE% -d "%SOLR_SERVER_DIR%" ^
+ -urlScheme !SOLR_URL_SCHEME! !PASS_TO_RUN_EXAMPLE!
+
+REM End of run_example
+goto done
+
+:get_info
+REM Find all Java processes, correlate with those listening on a port
+REM and then try to contact via that port using the status tool
+for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" (
+ if "%%j"=="%SOLR_JETTY_HOST%:!SOME_SOLR_PORT!" (
+ @echo.
+ set has_info=1
+ echo Found Solr process %%k running on port !SOME_SOLR_PORT!
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI status -solr !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!SOME_SOLR_PORT!/solr
+ @echo.
+ )
+ )
+ )
+ )
+)
+if NOT "!has_info!"=="1" echo No running Solr nodes found.
+set has_info=
+goto done
+
+:parse_healthcheck_args
+IF [%1]==[] goto run_healthcheck
+IF "%1"=="-V" goto set_healthcheck_verbose
+IF "%1"=="-c" goto set_healthcheck_collection
+IF "%1"=="-collection" goto set_healthcheck_collection
+IF "%1"=="-z" goto set_healthcheck_zk
+IF "%1"=="-zkhost" goto set_healthcheck_zk
+IF "%1"=="-zkHost" goto set_healthcheck_zk
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+goto run_healthcheck
+
+:set_healthcheck_verbose
+set HEALTHCHECK_VERBOSE="-verbose"
+SHIFT
+goto parse_healthcheck_args
+
+:set_healthcheck_collection
+set HEALTHCHECK_COLLECTION=%~2
+SHIFT
+SHIFT
+goto parse_healthcheck_args
+
+:set_healthcheck_zk
+set ZK_HOST=%~2
+SHIFT
+SHIFT
+goto parse_healthcheck_args
+
+:run_healthcheck
+IF NOT DEFINED HEALTHCHECK_COLLECTION goto healthcheck_usage
+IF NOT DEFINED HEALTHCHECK_VERBOSE set "HEALTHCHECK_VERBOSE="
+IF NOT DEFINED HEALTHCHECK_ZK_HOST set "HEALTHCHECK_ZK_HOST=localhost:9983"
+echo ZK_HOST: !ZK_HOST!
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI healthcheck -collection !HEALTHCHECK_COLLECTION! -zkHost !ZK_HOST! %HEALTHCHECK_VERBOSE%
+goto done
+
+:run_assert
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI %*
+if errorlevel 1 (
+ exit /b 1
+)
+goto done
+
+:run_autoscaling
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI %*
+goto done
+
+:parse_config_args
+IF [%1]==[] goto run_config
+IF "%1"=="-z" goto set_config_zk
+IF "%1"=="-zkhost" goto set_config_zk
+IF "%1"=="-zkHost" goto set_config_zk
+IF "%1"=="-s" goto set_config_url_scheme
+IF "%1"=="-scheme" goto set_config_url_scheme
+set "CONFIG_ARGS=!CONFIG_ARGS! %1"
+SHIFT
+goto parse_config_args
+
+:set_config_zk
+set ZK_HOST=%~2
+SHIFT
+SHIFT
+goto parse_config_args
+
+:set_config_url_scheme
+set SOLR_URL_SCHEME=%~2
+SHIFT
+SHIFT
+goto parse_config_args
+
+:run_config
+IF NOT "!ZK_HOST!"=="" SET "CONFIG_ARGS=!CONFIG_ARGS! -z !ZK_HOST!"
+IF NOT "!SOLR_URL_SCHEME!"=="" SET "CONFIG_ARGS=!CONFIG_ARGS! -scheme !SOLR_URL_SCHEME!"
+
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI config !CONFIG_ARGS!
+if errorlevel 1 (
+ exit /b 1
+)
+goto done
+
+:get_version
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI version
+goto done
+
+:run_utils
+set "TOOL_CMD=%~1"
+set q="-q"
+IF "%verbose%"=="1" set q=""
+"%JAVA%" %SOLR_SSL_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI utils -s "%DEFAULT_SERVER_DIR%" -l "%SOLR_LOGS_DIR%" %q:"=% %TOOL_CMD%
+if errorlevel 1 (
+ exit /b 1
+)
+goto done
+
+:parse_create_args
+IF [%1]==[] goto run_create
+IF "%1"=="-V" goto set_create_verbose
+IF "%1"=="-c" goto set_create_name
+IF "%1"=="-core" goto set_create_name
+IF "%1"=="-collection" goto set_create_name
+IF "%1"=="-d" goto set_create_confdir
+IF "%1"=="-confdir" goto set_create_confdir
+IF "%1"=="-n" goto set_create_confname
+IF "%1"=="-confname" goto set_create_confname
+IF "%1"=="-s" goto set_create_shards
+IF "%1"=="-shards" goto set_create_shards
+IF "%1"=="-rf" goto set_create_rf
+IF "%1"=="-replicationFactor" goto set_create_rf
+IF "%1"=="-p" goto set_create_port
+IF "%1"=="-port" goto set_create_port
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+goto run_create
+
+
+:set_create_verbose
+set CREATE_VERBOSE="-verbose"
+SHIFT
+goto parse_create_args
+
+:set_create_name
+set CREATE_NAME=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_confdir
+set CREATE_CONFDIR=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_confname
+set CREATE_CONFNAME=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_port
+set CREATE_PORT=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_shards
+set CREATE_NUM_SHARDS=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:set_create_rf
+set CREATE_REPFACT=%~2
+SHIFT
+SHIFT
+goto parse_create_args
+
+:run_create
+IF "!CREATE_NAME!"=="" (
+ set "SCRIPT_ERROR=Name (-c) is a required parameter for %SCRIPT_CMD%"
+ goto invalid_cmd_line
+)
+IF NOT DEFINED CREATE_VERBOSE set "CREATE_VERBOSE="
+IF "!CREATE_CONFDIR!"=="" set CREATE_CONFDIR=_default
+IF "!CREATE_NUM_SHARDS!"=="" set CREATE_NUM_SHARDS=1
+IF "!CREATE_REPFACT!"=="" set CREATE_REPFACT=1
+IF "!CREATE_CONFNAME!"=="" set CREATE_CONFNAME=!CREATE_NAME!
+
+REM Find a port that Solr is running on
+if "!CREATE_PORT!"=="" (
+ for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" set CREATE_PORT=!SOME_SOLR_PORT!
+ )
+ )
+ )
+)
+if "!CREATE_PORT!"=="" (
+ set "SCRIPT_ERROR=Could not find a running Solr instance on this host! Please use the -p option to specify the port."
+ goto err
+)
+
+if "!CREATE_CONFDIR!"=="_default" (
+ echo WARNING: Using _default configset with data driven schema functionality. NOT RECOMMENDED for production use.
+ echo To turn off: bin\solr config -c !CREATE_NAME! -p !CREATE_PORT! -action set-user-property -property update.autoCreateFields -value false
+)
+
+if "%SCRIPT_CMD%"=="create_core" (
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI create_core -name !CREATE_NAME! -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!CREATE_PORT!/solr ^
+ -confdir !CREATE_CONFDIR! -configsetsDir "%SOLR_TIP%\server\solr\configsets" %CREATE_VERBOSE%
+) else (
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dsolr.default.confdir="%DEFAULT_CONFDIR%"^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI create -name !CREATE_NAME! -shards !CREATE_NUM_SHARDS! -replicationFactor !CREATE_REPFACT! ^
+ -confname !CREATE_CONFNAME! -confdir !CREATE_CONFDIR! -configsetsDir "%SOLR_TIP%\server\solr\configsets" ^
+ -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!CREATE_PORT!/solr %CREATE_VERBOSE%
+)
+
+goto done
+
+:parse_delete_args
+IF [%1]==[] goto run_delete
+IF "%1"=="-V" goto set_delete_verbose
+IF "%1"=="-c" goto set_delete_name
+IF "%1"=="-core" goto set_delete_name
+IF "%1"=="-collection" goto set_delete_name
+IF "%1"=="-p" goto set_delete_port
+IF "%1"=="-port" goto set_delete_port
+IF "%1"=="-deleteConfig" goto set_delete_config
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+IF "%1"=="/?" goto usage
+goto run_delete
+
+:set_delete_verbose
+set DELETE_VERBOSE="-verbose"
+SHIFT
+goto parse_delete_args
+
+:set_delete_name
+set DELETE_NAME=%~2
+SHIFT
+SHIFT
+goto parse_delete_args
+
+:set_delete_port
+set DELETE_PORT=%~2
+SHIFT
+SHIFT
+goto parse_delete_args
+
+:set_delete_config
+set DELETE_CONFIG=%~2
+SHIFT
+SHIFT
+goto parse_delete_args
+
+:run_delete
+IF NOT DEFINED DELETE_VERBOSE set "DELETE_VERBOSE="
+IF "!DELETE_NAME!"=="" (
+ set "SCRIPT_ERROR=Name (-c) is a required parameter for %SCRIPT_CMD%"
+ goto invalid_cmd_line
+)
+
+REM Find a port that Solr is running on
+if "!DELETE_PORT!"=="" (
+ for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" set DELETE_PORT=!SOME_SOLR_PORT!
+ )
+ )
+ )
+)
+if "!DELETE_PORT!"=="" (
+ set "SCRIPT_ERROR=Could not find a running Solr instance on this host! Please use the -p option to specify the port."
+ goto err
+)
+
+if "!DELETE_CONFIG!"=="" (
+ set DELETE_CONFIG=true
+)
+
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+-Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+-classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+org.apache.solr.util.SolrCLI delete -name !DELETE_NAME! -deleteConfig !DELETE_CONFIG! ^
+-solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!DELETE_PORT!/solr %DELETE_VERBOSE%
+
+goto done
+
+REM Clumsy to do the state machine thing for -d and -n, but that's required for back-compat
+:parse_zk_args
+IF "%1"=="-upconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="-V" (
+ goto set_zk_verbose
+) ELSE IF "%1"=="upconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="-downconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="downconfig" (
+ goto set_zk_op
+) ELSE IF "%1"=="cp" (
+ goto set_zk_op
+) ELSE IF "%1"=="mv" (
+ goto set_zk_op
+) ELSE IF "%1"=="rm" (
+ goto set_zk_op
+) ELSE IF "%1"=="ls" (
+ goto set_zk_op
+) ELSE IF "%1"=="mkroot" (
+ goto set_zk_op
+) ELSE IF "%1"=="-n" (
+ goto set_config_name
+) ELSE IF "%1"=="-r" (
+ goto set_zk_recurse
+) ELSE IF "%1"=="-configname" (
+ goto set_config_name
+) ELSE IF "%1"=="-d" (
+ goto set_configdir
+) ELSE IF "%1"=="-confdir" (
+ goto set_configdir
+) ELSE IF "%1"=="-z" (
+ goto set_config_zk
+) ELSE IF "%1"=="/?" (
+ goto zk_usage
+) ELSE IF "%1"=="-h" (
+ goto zk_usage
+) ELSE IF "%1"=="-help" (
+ goto zk_usage
+) ELSE IF "!ZK_SRC!"=="" (
+ if not "%~1"=="" (
+ goto set_zk_src
+ )
+) ELSE IF "!ZK_DST!"=="" (
+ IF "%ZK_OP%"=="cp" (
+ goto set_zk_dst
+ )
+ IF "%ZK_OP%"=="mv" (
+ goto set_zk_dst
+ )
+ set ZK_DST="_"
+) ELSE IF NOT "%1"=="" (
+ set ERROR_MSG="Unrecognized or misplaced zk argument %1%"
+ goto zk_short_usage
+)
+goto run_zk
+
+:set_zk_op
+set ZK_OP=%~1
+SHIFT
+goto parse_zk_args
+
+:set_zk_verbose
+set ZK_VERBOSE="-verbose"
+SHIFT
+goto parse_zk_args
+
+:set_config_name
+set CONFIGSET_NAME=%~2
+SHIFT
+SHIFT
+goto parse_zk_args
+
+:set_configdir
+set CONFIGSET_DIR=%~2
+SHIFT
+SHIFT
+goto parse_zk_args
+
+:set_config_zk
+set ZK_HOST=%~2
+SHIFT
+SHIFT
+goto parse_zk_args
+
+:set_zk_src
+set ZK_SRC=%~1
+SHIFT
+goto parse_zk_args
+
+:set_zk_dst
+set ZK_DST=%~1
+SHIFT
+goto parse_zk_args
+
+:set_zk_recurse
+set ZK_RECURSE="true"
+SHIFT
+goto parse_zk_args
+
+:run_zk
+IF "!ZK_OP!"=="" (
+ set "ERROR_MSG=Invalid command specified for zk sub-command"
+ goto zk_short_usage
+)
+
+IF "!ZK_HOST!"=="" (
+ set "ERROR_MSG=Must specify -z zkHost"
+ goto zk_short_usage
+)
+
+IF "!ZK_OP!"=="-upconfig" (
+ set ZK_OP="upconfig"
+)
+IF "!ZK_OP!"=="-downconfig" (
+ set ZK_OP="downconfig"
+)
+
+IF "!ZK_OP!"=="upconfig" (
+ IF "!CONFIGSET_NAME!"=="" (
+ set ERROR_MSG="-n option must be set for upconfig"
+ goto zk_short_usage
+ )
+ IF "!CONFIGSET_DIR!"=="" (
+ set ERROR_MSG="The -d option must be set for upconfig."
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -confname !CONFIGSET_NAME! -confdir !CONFIGSET_DIR! -zkHost !ZK_HOST! %ZK_VERBOSE%^
+ -configsetsDir "%SOLR_TIP%/server/solr/configsets"
+) ELSE IF "!ZK_OP!"=="downconfig" (
+ IF "!CONFIGSET_NAME!"=="" (
+ set ERROR_MSG="-n option must be set for downconfig"
+ goto zk_short_usage
+ )
+ IF "!CONFIGSET_DIR!"=="" (
+ set ERROR_MSG="The -d option must be set for downconfig."
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -confname !CONFIGSET_NAME! -confdir !CONFIGSET_DIR! -zkHost !ZK_HOST! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="cp" (
+ IF "%ZK_SRC%"=="" (
+ set ERROR_MSG=" must be specified for 'cp' command"
+ goto zk_short_usage
+ )
+ IF "%ZK_DST%"=="" (
+ set ERROR_MSG= must be specified for 'cp' command"
+ goto zk_short_usage
+ )
+ IF NOT "!ZK_SRC:~0,3!"=="zk:" (
+ IF NOT "!%ZK_DST:~0,3!"=="zk:" (
+ set ERROR_MSG="At least one of src or dst must be prefixed by 'zk:'"
+ goto zk_short_usage
+ )
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -src !ZK_SRC! -dst !ZK_DST! -recurse !ZK_RECURSE! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="mv" (
+ IF "%ZK_SRC%"=="" (
+ set ERROR_MSG=" must be specified for 'mv' command"
+ goto zk_short_usage
+ )
+ IF "%ZK_DST%"=="" (
+ set ERROR_MSG=" must be specified for 'mv' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -src !ZK_SRC! -dst !ZK_DST! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="rm" (
+ IF "%ZK_SRC"=="" (
+ set ERROR_MSG="Zookeeper path to remove must be specified when using the 'rm' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -path !ZK_SRC! -recurse !ZK_RECURSE! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="ls" (
+ IF "%ZK_SRC"=="" (
+ set ERROR_MSG="Zookeeper path to remove must be specified when using the 'ls' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -path !ZK_SRC! -recurse !ZK_RECURSE! %ZK_VERBOSE%
+) ELSE IF "!ZK_OP!"=="mkroot" (
+ IF "%ZK_SRC"=="" (
+ set ERROR_MSG="Zookeeper path to create must be specified when using the 'mkroot' command"
+ goto zk_short_usage
+ )
+ "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%SOLR_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI !ZK_OP! -zkHost !ZK_HOST! -path !ZK_SRC! %ZK_VERBOSE%
+) ELSE (
+ set ERROR_MSG="Unknown zk option !ZK_OP!"
+ goto zk_short_usage
+)
+goto done
+
+
+:run_auth
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+
+REM Options parsing.
+REM Note: With the following technique of parsing, it is not possible
+REM to have an option without a value.
+set "AUTH_PARAMS=%1"
+set "option="
+for %%a in (%*) do (
+ if not defined option (
+ set arg=%%a
+ if "!arg:~0,1!" equ "-" set "option=!arg!"
+ ) else (
+ set "option!option!=%%a"
+ if "!option!" equ "-d" set "SOLR_SERVER_DIR=%%a"
+ if "!option!" equ "-s" set "SOLR_HOME=%%a"
+ if not "!option!" equ "-s" if not "!option!" equ "-d" (
+ set "AUTH_PARAMS=!AUTH_PARAMS! !option! %%a"
+ )
+ set "option="
+ )
+)
+IF "%SOLR_SERVER_DIR%"=="" set "SOLR_SERVER_DIR=%DEFAULT_SERVER_DIR%"
+IF NOT EXIST "%SOLR_SERVER_DIR%" (
+ set "SCRIPT_ERROR=Solr server directory %SOLR_SERVER_DIR% not found!"
+ goto err
+)
+IF "%SOLR_HOME%"=="" set "SOLR_HOME=%SOLR_SERVER_DIR%\solr"
+IF EXIST "%cd%\%SOLR_HOME%" set "SOLR_HOME=%cd%\%SOLR_HOME%"
+IF NOT EXIST "%SOLR_HOME%\" (
+ IF EXIST "%SOLR_SERVER_DIR%\%SOLR_HOME%" (
+ set "SOLR_HOME=%SOLR_SERVER_DIR%\%SOLR_HOME%"
+ ) ELSE (
+ set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% not found!"
+ goto err
+ )
+)
+
+if "!AUTH_PORT!"=="" (
+ for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
+ set SOME_SOLR_PORT=
+ For /F "Delims=" %%J In ('type "%SOLR_TIP%\bin\%%i"') do set SOME_SOLR_PORT=%%~J
+ if NOT "!SOME_SOLR_PORT!"=="" (
+ for /f "tokens=2,5" %%j in ('netstat -aon ^| find "TCP " ^| find ":0 " ^| find ":!SOME_SOLR_PORT! "') do (
+ IF NOT "%%k"=="0" set AUTH_PORT=!SOME_SOLR_PORT!
+ )
+ )
+ )
+)
+"%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
+ -Dlog4j.configurationFile="file:///%DEFAULT_SERVER_DIR%\resources\log4j2-console.xml" ^
+ -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
+ org.apache.solr.util.SolrCLI auth %AUTH_PARAMS% -solrIncludeFile "%SOLR_INCLUDE%" -authConfDir "%SOLR_HOME%" ^
+ -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!AUTH_PORT!/solr
+goto done
+
+
+:invalid_cmd_line
+@echo.
+IF "!SCRIPT_ERROR!"=="" (
+ @echo Invalid command-line option: %1
+) ELSE (
+ @echo ERROR: !SCRIPT_ERROR!
+)
+@echo.
+IF "%FIRST_ARG%"=="start" (
+ goto start_usage
+) ELSE IF "%FIRST_ARG:~0,1%" == "-" (
+ goto start_usage
+) ELSE IF "%FIRST_ARG%"=="restart" (
+ goto start_usage
+) ELSE IF "%FIRST_ARG%"=="stop" (
+ goto stop_usage
+) ELSE IF "%FIRST_ARG%"=="healthcheck" (
+ goto healthcheck_usage
+) ELSE IF "%FIRST_ARG%"=="create" (
+ goto create_usage
+) ELSE IF "%FIRST_ARG%"=="create_core" (
+ goto create_core_usage
+) ELSE IF "%FIRST_ARG%"=="create_collection" (
+ goto create_collection_usage
+) ELSE IF "%FIRST_ARG%"=="zk" (
+ goto zk_short_usage
+) ELSE IF "%FIRST_ARG%"=="auth" (
+ goto auth_usage
+) ELSE IF "%FIRST_ARG%"=="status" (
+ goto status_usage
+) ELSE (
+ goto script_usage
+)
+
+:need_java_home
+@echo Please set the JAVA_HOME environment variable to the path where you installed Java 1.8+
+goto done
+
+:need_java_vers
+@echo Java 1.8 or later is required to run Solr.
+goto done
+
+:err
+@echo.
+@echo ERROR: !SCRIPT_ERROR!
+@echo.
+exit /b 1
+
+:done
+ENDLOCAL
+exit /b 0
+
+REM Tests what Java we have and sets some global variables
+:resolve_java_info
+
+CALL :resolve_java_vendor
+
+set JAVA_MAJOR_VERSION=0
+set JAVA_VERSION_INFO=
+set JAVA_BUILD=0
+
+FOR /f "usebackq tokens=3" %%a IN (`^""%JAVA%" -version 2^>^&1 ^| findstr "version"^"`) do (
+ set JAVA_VERSION_INFO=%%a
+ REM Remove surrounding quotes
+ set JAVA_VERSION_INFO=!JAVA_VERSION_INFO:"=!
+
+ REM Extract the major Java version, e.g. 7, 8, 9, 10 ...
+ for /f "tokens=1,2 delims=._-" %%a in ("!JAVA_VERSION_INFO!") do (
+ if %%a GEQ 9 (
+ set JAVA_MAJOR_VERSION=%%a
+ ) else (
+ set JAVA_MAJOR_VERSION=%%b
+ )
+ )
+
+ REM Don't look for "_{build}" if we're on IBM J9.
+ if NOT "%JAVA_VENDOR%" == "IBM J9" (
+ for /f "delims=_ tokens=2" %%a in ("!JAVA_VERSION_INFO!") do (
+ set /a JAVA_BUILD=%%a
+ )
+ )
+)
+GOTO :eof
+
+REM Set which JVM vendor we have
+:resolve_java_vendor
+"%JAVA%" -version 2>&1 | findstr /i "IBM J9" > nul
+if %ERRORLEVEL% == 1 ( set "JAVA_VENDOR=Oracle" ) else ( set "JAVA_VENDOR=IBM J9" )
+
+set JAVA_VENDOR_OUT=
+GOTO :eof
+
+REM Safe echo which does not mess with () in strings
+:safe_echo
+set "eout=%1"
+set eout=%eout:"=%
+echo !eout!
+GOTO :eof
diff --git a/KeywordSearch/solr/bin/solr.in.cmd b/KeywordSearch/solr/bin/solr.in.cmd
new file mode 100755
index 0000000000..c3c7302dda
--- /dev/null
+++ b/KeywordSearch/solr/bin/solr.in.cmd
@@ -0,0 +1,175 @@
+@REM
+@REM Licensed to the Apache Software Foundation (ASF) under one or more
+@REM contributor license agreements. See the NOTICE file distributed with
+@REM this work for additional information regarding copyright ownership.
+@REM The ASF licenses this file to You under the Apache License, Version 2.0
+@REM (the "License"); you may not use this file except in compliance with
+@REM the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing, software
+@REM distributed under the License is distributed on an "AS IS" BASIS,
+@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@REM See the License for the specific language governing permissions and
+@REM limitations under the License.
+
+@echo off
+
+REM Settings here will override settings in existing env vars or in bin/solr. The default shipped state
+REM of this file is completely commented.
+
+REM By default the script will use JAVA_HOME to determine which java
+REM to use, but you can set a specific path for Solr to use without
+REM affecting other Java applications on your server/workstation.
+REM set SOLR_JAVA_HOME=
+
+REM Increase Java Min/Max Heap as needed to support your indexing / query needs
+REM set SOLR_JAVA_MEM=-Xms512m -Xmx512m
+
+REM Configure verbose GC logging:
+REM For Java 8: if this is set, additional params will be added to specify the log file & rotation
+REM For Java 9 or higher: GC_LOG_OPTS is currently not supported. If you set it, the startup script will exit with failure.
+REM set GC_LOG_OPTS=-verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime
+
+REM Various GC settings have shown to work well for a number of common Solr workloads.
+REM See solr.cmd GC_TUNE for the default list.
+REM set GC_TUNE=-XX:SurvivorRatio=4
+REM set GC_TUNE=%GC_TUNE% -XX:TargetSurvivorRatio=90
+REM set GC_TUNE=%GC_TUNE% -XX:MaxTenuringThreshold=8
+REM set GC_TUNE=%GC_TUNE% -XX:+UseConcMarkSweepGC
+REM set GC_TUNE=%GC_TUNE% -XX:ConcGCThreads=4
+REM set GC_TUNE=%GC_TUNE% -XX:ParallelGCThreads=4
+REM set GC_TUNE=%GC_TUNE% -XX:+CMSScavengeBeforeRemark
+REM set GC_TUNE=%GC_TUNE% -XX:PretenureSizeThreshold=64m
+REM set GC_TUNE=%GC_TUNE% -XX:+UseCMSInitiatingOccupancyOnly
+REM set GC_TUNE=%GC_TUNE% -XX:CMSInitiatingOccupancyFraction=50
+REM set GC_TUNE=%GC_TUNE% -XX:CMSMaxAbortablePrecleanTime=6000
+REM set GC_TUNE=%GC_TUNE% -XX:+CMSParallelRemarkEnabled
+REM set GC_TUNE=%GC_TUNE% -XX:+ParallelRefProcEnabled
+REM set GC_TUNE=%GC_TUNE% -XX:-OmitStackTraceInFastThrow etc.
+
+REM Set the ZooKeeper connection string if using an external ZooKeeper ensemble
+REM e.g. host1:2181,host2:2181/chroot
+REM Leave empty if not using SolrCloud
+REM set ZK_HOST=
+
+REM Set the ZooKeeper client timeout (for SolrCloud mode)
+REM set ZK_CLIENT_TIMEOUT=15000
+
+REM By default the start script uses "localhost"; override the hostname here
+REM for production SolrCloud environments to control the hostname exposed to cluster state
+REM set SOLR_HOST=192.168.1.1
+
+REM By default Solr will try to connect to Zookeeper with 30 seconds in timeout; override the timeout if needed
+REM set SOLR_WAIT_FOR_ZK=30
+
+REM By default the start script uses UTC; override the timezone if needed
+REM set SOLR_TIMEZONE=UTC
+
+REM Set to true to activate the JMX RMI connector to allow remote JMX client applications
+REM to monitor the JVM hosting Solr; set to "false" to disable that behavior
+REM (false is recommended in production environments)
+REM set ENABLE_REMOTE_JMX_OPTS=false
+
+REM The script will use SOLR_PORT+10000 for the RMI_PORT or you can set it here
+REM set RMI_PORT=18983
+
+REM Anything you add to the SOLR_OPTS variable will be included in the java
+REM start command line as-is, in ADDITION to other options. If you specify the
+REM -a option on start script, those options will be appended as well. Examples:
+set SOLR_OPTS=%SOLR_OPTS% -Dbootstrap_confdir="C:\Bitnami\solr-8.2.0-2\apache-solr\server\solr\configsets\AutopsyConfig\conf"
+set SOLR_OPTS=%SOLR_OPTS% -Dcollection.configName=AutopsyConfig
+set SOLR_OPTS=%SOLR_OPTS% -Dsolr.default.confdir="C:\Bitnami\solr-8.2.0-2\apache-solr\server\solr\configsets\AutopsyConfig\conf"
+
+REM Path to a directory for Solr to store cores and their data. By default, Solr will use server\solr
+REM If solr.xml is not stored in ZooKeeper, this directory needs to contain solr.xml
+REM set SOLR_HOME=
+
+REM Path to a directory that Solr will use as root for data folders for each core.
+REM If not set, defaults to /data. Overridable per core through 'dataDir' core property
+REM set SOLR_DATA_HOME=
+
+REM Changes the logging level. Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. Default is INFO
+REM This is an alternative to changing the rootLogger in log4j2.xml
+REM set SOLR_LOG_LEVEL=INFO
+
+REM Location where Solr should write logs to. Absolute or relative to solr start dir
+REM set SOLR_LOGS_DIR=logs
+
+REM Enables log rotation before starting Solr. Setting SOLR_LOG_PRESTART_ROTATION=true will let Solr take care of pre
+REM start rotation of logs. This is false by default as log4j2 handles this for us. If you choose to use another log
+REM framework that cannot do startup rotation, you may want to enable this to let Solr rotate logs on startup.
+REM set SOLR_LOG_PRESTART_ROTATION=false
+
+REM Set the host interface to listen on. Jetty will listen on all interfaces (0.0.0.0) by default.
+REM This must be an IPv4 ("a.b.c.d") or bracketed IPv6 ("[x::y]") address, not a hostname!
+REM set SOLR_JETTY_HOST=0.0.0.0
+
+REM Sets the port Solr binds to, default is 8983
+REM set SOLR_PORT=8983
+
+REM Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
+REM to enable https module with custom jetty configuration.
+REM set SOLR_SSL_ENABLED=true
+REM Uncomment to set SSL-related system properties
+REM Be sure to update the paths to the correct keystore for your environment
+REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
+REM set SOLR_SSL_KEY_STORE_PASSWORD=secret
+REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks
+REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret
+REM Require clients to authenticate
+REM set SOLR_SSL_NEED_CLIENT_AUTH=false
+REM Enable clients to authenticate (but not require)
+REM set SOLR_SSL_WANT_CLIENT_AUTH=false
+REM SSL Certificates contain host/ip "peer name" information that is validated by default. Setting
+REM this to false can be useful to disable these checks when re-using a certificate on many hosts
+REM set SOLR_SSL_CHECK_PEER_NAME=true
+REM Override Key/Trust Store types if necessary
+REM set SOLR_SSL_KEY_STORE_TYPE=JKS
+REM set SOLR_SSL_TRUST_STORE_TYPE=JKS
+
+REM Uncomment if you want to override previously defined SSL values for HTTP client
+REM otherwise keep them commented and the above values will automatically be set for HTTP clients
+REM set SOLR_SSL_CLIENT_KEY_STORE=
+REM set SOLR_SSL_CLIENT_KEY_STORE_PASSWORD=
+REM set SOLR_SSL_CLIENT_TRUST_STORE=
+REM set SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD=
+REM set SOLR_SSL_CLIENT_KEY_STORE_TYPE=
+REM set SOLR_SSL_CLIENT_TRUST_STORE_TYPE=
+
+REM Sets path of Hadoop credential provider (hadoop.security.credential.provider.path property) and
+REM enables usage of credential store.
+REM Credential provider should store the following keys:
+REM * solr.jetty.keystore.password
+REM * solr.jetty.truststore.password
+REM Set the two below if you want to set specific store passwords for HTTP client
+REM * javax.net.ssl.keyStorePassword
+REM * javax.net.ssl.trustStorePassword
+REM More info: https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/CredentialProviderAPI.html
+REM set SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks
+REM set SOLR_OPTS=" -Dsolr.ssl.credential.provider.chain=hadoop"
+
+REM Settings for authentication
+REM Please configure only one of SOLR_AUTHENTICATION_CLIENT_BUILDER or SOLR_AUTH_TYPE parameters
+REM set SOLR_AUTHENTICATION_CLIENT_BUILDER=org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory
+REM set SOLR_AUTH_TYPE=basic
+REM set SOLR_AUTHENTICATION_OPTS="-Dbasicauth=solr:SolrRocks"
+
+REM Settings for ZK ACL
+REM set SOLR_ZK_CREDS_AND_ACLS=-DzkACLProvider=org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider ^
+REM -DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider ^
+REM -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD ^
+REM -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD
+REM set SOLR_OPTS=%SOLR_OPTS% %SOLR_ZK_CREDS_AND_ACLS%
+
+REM When running Solr in non-cloud mode and if planning to do distributed search (using the "shards" parameter), the
+REM list of hosts needs to be whitelisted or Solr will forbid the request. The whitelist can be configured in solr.xml,
+REM or if you are using the OOTB solr.xml, can be specified using the system property "solr.shardsWhitelist". Alternatively
+REM host checking can be disabled by using the system property "solr.disable.shardsWhitelist"
+REM set SOLR_OPTS="%SOLR_OPTS% -Dsolr.shardsWhitelist=http://localhost:8983,http://localhost:8984"
+
+REM For a visual indication in the Admin UI of what type of environment this cluster is, configure
+REM a -Dsolr.environment property below. Valid values are prod, stage, test, dev, with an optional
+REM label or color, e.g. -Dsolr.environment=test,label=Functional+test,color=brown
+REM SOLR_OPTS="$SOLR_OPTS -Dsolr.environment=prod"
diff --git a/KeywordSearch/solr/bin/solr.in.sh b/KeywordSearch/solr/bin/solr.in.sh
new file mode 100755
index 0000000000..bbded6f238
--- /dev/null
+++ b/KeywordSearch/solr/bin/solr.in.sh
@@ -0,0 +1,203 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Settings here will override settings in existing env vars or in bin/solr. The default shipped state
+# of this file is completely commented.
+
+# By default the script will use JAVA_HOME to determine which java
+# to use, but you can set a specific path for Solr to use without
+# affecting other Java applications on your server/workstation.
+SOLR_JAVA_HOME="C:\Program Files\ojdkbuild\java-1.8.0-openjdk-1.8.0.222-1"
+
+# This controls the number of seconds that the solr script will wait for
+# Solr to stop gracefully or Solr to start. If the graceful stop fails,
+# the script will forcibly stop Solr. If the start fails, the script will
+# give up waiting and display the last few lines of the logfile.
+#SOLR_STOP_WAIT="180"
+
+# Increase Java Heap as needed to support your indexing / query needs
+#SOLR_HEAP="512m"
+
+# Expert: If you want finer control over memory options, specify them directly
+# Comment out SOLR_HEAP if you are using this though, that takes precedence
+#SOLR_JAVA_MEM="-Xms512m -Xmx512m"
+
+# Enable verbose GC logging...
+# * If this is unset, various default options will be selected depending on which JVM version is in use
+# * For Java 8: if this is set, additional params will be added to specify the log file & rotation
+# * For Java 9 or higher: each included opt param that starts with '-Xlog:gc', but does not include an
+# output specifier, will have a 'file' output specifier (as well as formatting & rollover options)
+# appended, using the effective value of the SOLR_LOGS_DIR.
+#
+#GC_LOG_OPTS='-Xlog:gc*' # (Java 9+)
+#GC_LOG_OPTS="-verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails \
+# -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime"
+
+# These GC settings have shown to work well for a number of common Solr workloads
+#GC_TUNE=" \
+#-XX:SurvivorRatio=4 \
+#-XX:TargetSurvivorRatio=90 \
+#-XX:MaxTenuringThreshold=8 \
+#-XX:+UseConcMarkSweepGC \
+#-XX:ConcGCThreads=4 -XX:ParallelGCThreads=4 \
+#-XX:+CMSScavengeBeforeRemark \
+#-XX:PretenureSizeThreshold=64m \
+#-XX:+UseCMSInitiatingOccupancyOnly \
+#-XX:CMSInitiatingOccupancyFraction=50 \
+#-XX:CMSMaxAbortablePrecleanTime=6000 \
+#-XX:+CMSParallelRemarkEnabled \
+#-XX:+ParallelRefProcEnabled \
+#-XX:-OmitStackTraceInFastThrow etc.
+
+# Set the ZooKeeper connection string if using an external ZooKeeper ensemble
+# e.g. host1:2181,host2:2181/chroot
+# Leave empty if not using SolrCloud
+#ZK_HOST=""
+
+# Set the ZooKeeper client timeout (for SolrCloud mode)
+#ZK_CLIENT_TIMEOUT="15000"
+
+# By default the start script uses "localhost"; override the hostname here
+# for production SolrCloud environments to control the hostname exposed to cluster state
+#SOLR_HOST="192.168.1.1"
+
+# By default Solr will try to connect to Zookeeper with 30 seconds in timeout; override the timeout if needed
+#SOLR_WAIT_FOR_ZK="30"
+
+# By default the start script uses UTC; override the timezone if needed
+#SOLR_TIMEZONE="UTC"
+
+# Set to true to activate the JMX RMI connector to allow remote JMX client applications
+# to monitor the JVM hosting Solr; set to "false" to disable that behavior
+# (false is recommended in production environments)
+ENABLE_REMOTE_JMX_OPTS="true"
+
+# The script will use SOLR_PORT+10000 for the RMI_PORT or you can set it here
+# RMI_PORT=18983
+
+# Anything you add to the SOLR_OPTS variable will be included in the java
+# start command line as-is, in ADDITION to other options. If you specify the
+# -a option on start script, those options will be appended as well. Examples:
+SOLR_OPTS="$SOLR_OPTS -Dcollection.configName=AutopsyConfig"
+SOLR_OPTS="$SOLR_OPTS -Dbootstrap_confdir=C:\Bitnami\solr-8.2.0-2\apache-solr\server\solr\configsets\AutopsyConfig\conf"
+SOLR_OPTS="$SOLR_OPTS -Dsolr.default.confdir=C:\Bitnami\solr-8.2.0-2\apache-solr\server\solr\configsets\AutopsyConfig\conf"
+
+# Location where the bin/solr script will save PID files for running instances
+# If not set, the script will create PID files in $SOLR_TIP/bin
+#SOLR_PID_DIR=
+
+# Path to a directory for Solr to store cores and their data. By default, Solr will use server/solr
+# If solr.xml is not stored in ZooKeeper, this directory needs to contain solr.xml
+#SOLR_HOME=
+
+# Path to a directory that Solr will use as root for data folders for each core.
+# If not set, defaults to /data. Overridable per core through 'dataDir' core property
+#SOLR_DATA_HOME=
+
+# Solr provides a default Log4J configuration xml file in server/resources
+# however, you may want to customize the log settings and file appender location
+# so you can point the script to use a different log4j2.xml file
+#LOG4J_PROPS=/var/solr/log4j2.xml
+
+# Changes the logging level. Valid values: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. Default is INFO
+# This is an alternative to changing the rootLogger in log4j2.xml
+#SOLR_LOG_LEVEL=INFO
+
+# Location where Solr should write logs to. Absolute or relative to solr start dir
+#SOLR_LOGS_DIR=logs
+
+# Enables log rotation before starting Solr. Setting SOLR_LOG_PRESTART_ROTATION=true will let Solr take care of pre
+# start rotation of logs. This is false by default as log4j2 handles this for us. If you choose to use another log
+# framework that cannot do startup rotation, you may want to enable this to let Solr rotate logs on startup.
+#SOLR_LOG_PRESTART_ROTATION=false
+
+# Sets the port Solr binds to, default is 8983
+#SOLR_PORT=8983
+
+# Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
+# to enable https module with custom jetty configuration.
+#SOLR_SSL_ENABLED=true
+# Uncomment to set SSL-related system properties
+# Be sure to update the paths to the correct keystore for your environment
+#SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks
+#SOLR_SSL_KEY_STORE_PASSWORD=secret
+#SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks
+#SOLR_SSL_TRUST_STORE_PASSWORD=secret
+# Require clients to authenticate
+#SOLR_SSL_NEED_CLIENT_AUTH=false
+# Enable clients to authenticate (but not require)
+#SOLR_SSL_WANT_CLIENT_AUTH=false
+# SSL Certificates contain host/ip "peer name" information that is validated by default. Setting
+# this to false can be useful to disable these checks when re-using a certificate on many hosts
+#SOLR_SSL_CHECK_PEER_NAME=true
+# Override Key/Trust Store types if necessary
+#SOLR_SSL_KEY_STORE_TYPE=JKS
+#SOLR_SSL_TRUST_STORE_TYPE=JKS
+
+# Uncomment if you want to override previously defined SSL values for HTTP client
+# otherwise keep them commented and the above values will automatically be set for HTTP clients
+#SOLR_SSL_CLIENT_KEY_STORE=
+#SOLR_SSL_CLIENT_KEY_STORE_PASSWORD=
+#SOLR_SSL_CLIENT_TRUST_STORE=
+#SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD=
+#SOLR_SSL_CLIENT_KEY_STORE_TYPE=
+#SOLR_SSL_CLIENT_TRUST_STORE_TYPE=
+
+# Sets path of Hadoop credential provider (hadoop.security.credential.provider.path property) and
+# enables usage of credential store.
+# Credential provider should store the following keys:
+# * solr.jetty.keystore.password
+# * solr.jetty.truststore.password
+# Set the two below if you want to set specific store passwords for HTTP client
+# * javax.net.ssl.keyStorePassword
+# * javax.net.ssl.trustStorePassword
+# More info: https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/CredentialProviderAPI.html
+#SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks
+#SOLR_OPTS=" -Dsolr.ssl.credential.provider.chain=hadoop"
+
+# Settings for authentication
+# Please configure only one of SOLR_AUTHENTICATION_CLIENT_BUILDER or SOLR_AUTH_TYPE parameters
+#SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"
+#SOLR_AUTH_TYPE="basic"
+#SOLR_AUTHENTICATION_OPTS="-Dbasicauth=solr:SolrRocks"
+
+# Settings for ZK ACL
+#SOLR_ZK_CREDS_AND_ACLS="-DzkACLProvider=org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider \
+# -DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider \
+# -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD \
+# -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD"
+#SOLR_OPTS="$SOLR_OPTS $SOLR_ZK_CREDS_AND_ACLS"
+
+
+# Settings for common system values that may cause operational imparement when system defaults are used.
+# Solr can use many processes and many file handles. On modern operating systems the savings by leaving
+# these settings low is minuscule, while the consequence can be Solr instability. To turn these checks off, set
+# SOLR_ULIMIT_CHECKS=false either here or as part of your profile.
+
+# Different limits can be set in solr.in.sh or your profile if you prefer as well.
+#SOLR_RECOMMENDED_OPEN_FILES=
+#SOLR_RECOMMENDED_MAX_PROCESSES=
+#SOLR_ULIMIT_CHECKS=
+
+# When running Solr in non-cloud mode and if planning to do distributed search (using the "shards" parameter), the
+# list of hosts needs to be whitelisted or Solr will forbid the request. The whitelist can be configured in solr.xml,
+# or if you are using the OOTB solr.xml, can be specified using the system property "solr.shardsWhitelist". Alternatively
+# host checking can be disabled by using the system property "solr.disable.shardsWhitelist"
+#SOLR_OPTS="$SOLR_OPTS -Dsolr.shardsWhitelist=http://localhost:8983,http://localhost:8984"
+
+# For a visual indication in the Admin UI of what type of environment this cluster is, configure
+# a -Dsolr.environment property below. Valid values are prod, stage, test, dev, with an optional
+# label or color, e.g. -Dsolr.environment=test,label=Functional+test,color=brown
+#SOLR_OPTS="$SOLR_OPTS -Dsolr.environment=prod"
diff --git a/KeywordSearch/solr/server/README.txt b/KeywordSearch/solr/server/README.txt
new file mode 100755
index 0000000000..d4b421cac3
--- /dev/null
+++ b/KeywordSearch/solr/server/README.txt
@@ -0,0 +1,109 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Solr server
+------------
+
+This directory contains an instance of the Jetty Servlet container setup to
+run Solr.
+
+To run Solr:
+
+ cd $SOLR_INSTALL
+ bin/solr start
+
+where $SOLR_INSTALL is the location where you extracted the Solr installation bundle.
+
+Server directory layout
+-----------------------
+
+server/contexts
+
+ This directory contains the Jetty Web application deployment descriptor for the Solr Web app.
+
+server/etc
+
+ Jetty configuration and example SSL keystore
+
+server/lib
+
+ Jetty and other 3rd party libraries
+
+server/logs
+
+ Solr log files
+
+server/resources
+
+ Contains configuration files, such as the Log4j configuration (log4j2.xml) for configuring Solr loggers.
+
+server/scripts/cloud-scripts
+
+ Command-line utility for working with ZooKeeper when running in SolrCloud mode, see zkcli.sh / .cmd for
+ usage information.
+
+server/solr
+
+ Default solr.solr.home directory where Solr will create core directories; must contain solr.xml
+
+server/solr/configsets
+
+ Directories containing different configuration options for running Solr.
+
+ _default : Bare minimum configurations with field-guessing and managed schema turned
+ on by default, so as to start indexing data in Solr without having to design
+ a schema upfront. You can use the REST API to manage your schema as you refine your index
+ requirements. You can turn off the field (for a collection, say mycollection) guessing by:
+ curl http://host:8983/solr/mycollection/config -d '{"set-user-property": {"update.autoCreateFields":"false"}}'
+
+ sample_techproducts_configs : Comprehensive example configuration that demonstrates many of the powerful
+ features of Solr, based on the use case of building a search solution for
+ tech products.
+
+server/solr-webapp
+
+ Contains files used by the Solr server; do not edit files in this directory (Solr is not a Java Web application).
+
+
+Notes About Solr Examples
+--------------------------
+
+* SolrHome *
+
+By default, start.jar starts Solr in Jetty using the default Solr Home
+directory of "./solr/" (relative to the working directory of the servlet
+container).
+
+* References to Jar Files Outside This Directory *
+
+Various example SolrHome dirs contained in this directory may use ""
+statements in the solrconfig.xml file to reference plugin jars outside of
+this directory for loading "contrib" plugins via relative paths.
+
+If you make a copy of this example server and wish to use the
+ExtractingRequestHandler (SolrCell), DataImportHandler (DIH), the
+clustering component, or any other modules in "contrib", you will need to
+copy the required jars or update the paths to those jars in your
+solrconfig.xml.
+
+* Logging *
+
+By default, Jetty & Solr will log to the console and logs/solr.log. This can
+be convenient when first getting started, but eventually you will want to
+log just to a file. To configure logging, edit the log4j2.xml file in
+"resources".
+
+It is also possible to setup log4j or other popular logging frameworks.
+
diff --git a/KeywordSearch/solr/server/contexts/solr-jetty-context.xml b/KeywordSearch/solr/server/contexts/solr-jetty-context.xml
new file mode 100755
index 0000000000..6392cd11b7
--- /dev/null
+++ b/KeywordSearch/solr/server/contexts/solr-jetty-context.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ /solr-webapp/webapp
+ /etc/webdefault.xml
+ false
+
diff --git a/KeywordSearch/solr/server/etc/jetty-http.xml b/KeywordSearch/solr/server/etc/jetty-http.xml
new file mode 100755
index 0000000000..018cfe6c0e
--- /dev/null
+++ b/KeywordSearch/solr/server/etc/jetty-http.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/etc/jetty-https.xml b/KeywordSearch/solr/server/etc/jetty-https.xml
new file mode 100755
index 0000000000..41c3f197d7
--- /dev/null
+++ b/KeywordSearch/solr/server/etc/jetty-https.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ alpn
+
+
+
+
+
+
+
+ h2
+ http/1.1
+
+
+ http/1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeywordSearch/solr/server/etc/jetty-https8.xml b/KeywordSearch/solr/server/etc/jetty-https8.xml
new file mode 100755
index 0000000000..82e3a97136
--- /dev/null
+++ b/KeywordSearch/solr/server/etc/jetty-https8.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http/1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/etc/jetty-ssl.xml b/KeywordSearch/solr/server/etc/jetty-ssl.xml
new file mode 100755
index 0000000000..9ff5accf40
--- /dev/null
+++ b/KeywordSearch/solr/server/etc/jetty-ssl.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeywordSearch/solr/server/etc/jetty.xml b/KeywordSearch/solr/server/etc/jetty.xml
new file mode 100755
index 0000000000..1f6de775a4
--- /dev/null
+++ b/KeywordSearch/solr/server/etc/jetty.xml
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ solr.jetty
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ https
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ false
+ requestedPath
+
+
+
+
+ ^/$
+ /solr/
+
+
+
+
+
+
+ /v2/*
+ /solr/____v2
+
+
+
+
+
+
+ /api/*
+ /solr/____v2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ false
+ false
+
+
+
+
+
+
+
+
+ org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern
+ .*/servlet-api-[^/]*\.jar$
+
+
+
+
+
+ /contexts
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeywordSearch/solr/server/etc/webdefault.xml b/KeywordSearch/solr/server/etc/webdefault.xml
new file mode 100755
index 0000000000..f0882926a9
--- /dev/null
+++ b/KeywordSearch/solr/server/etc/webdefault.xml
@@ -0,0 +1,527 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default web.xml file.
+ This file is applied to a Web application before its own WEB_INF/web.xml file
+
+
+
+
+
+
+
+ org.eclipse.jetty.servlet.listener.ELContextCleaner
+
+
+
+
+
+
+
+ org.eclipse.jetty.servlet.listener.IntrospectorCleaner
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ default
+ org.eclipse.jetty.servlet.DefaultServlet
+
+ aliases
+ false
+
+
+ acceptRanges
+ true
+
+
+ dirAllowed
+ false
+
+
+ welcomeServlets
+ false
+
+
+ redirectWelcome
+ false
+
+
+ maxCacheSize
+ 256000000
+
+
+ maxCachedFileSize
+ 200000000
+
+
+ maxCachedFiles
+ 2048
+
+
+ gzip
+ true
+
+
+ useFileMappedBuffer
+ true
+
+
+
+ 0
+
+
+
+ default
+ /
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jsp
+ org.apache.jasper.servlet.JspServlet
+
+ logVerbosityLevel
+ DEBUG
+
+
+ fork
+ false
+
+
+ xpoweredBy
+ false
+
+
+ 0
+
+
+
+ jsp
+ *.jsp
+ *.jspf
+ *.jspx
+ *.xsp
+ *.JSP
+ *.JSPF
+ *.JSPX
+ *.XSP
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 30
+
+
+
+
+
+
+
+
+
+
+
+
+ index.html
+ index.htm
+ index.jsp
+
+
+
+
+
+ ar
+ ISO-8859-6
+
+
+ be
+ ISO-8859-5
+
+
+ bg
+ ISO-8859-5
+
+
+ ca
+ ISO-8859-1
+
+
+ cs
+ ISO-8859-2
+
+
+ da
+ ISO-8859-1
+
+
+ de
+ ISO-8859-1
+
+
+ el
+ ISO-8859-7
+
+
+ en
+ ISO-8859-1
+
+
+ es
+ ISO-8859-1
+
+
+ et
+ ISO-8859-1
+
+
+ fi
+ ISO-8859-1
+
+
+ fr
+ ISO-8859-1
+
+
+ hr
+ ISO-8859-2
+
+
+ hu
+ ISO-8859-2
+
+
+ is
+ ISO-8859-1
+
+
+ it
+ ISO-8859-1
+
+
+ iw
+ ISO-8859-8
+
+
+ ja
+ Shift_JIS
+
+
+ ko
+ EUC-KR
+
+
+ lt
+ ISO-8859-2
+
+
+ lv
+ ISO-8859-2
+
+
+ mk
+ ISO-8859-5
+
+
+ nl
+ ISO-8859-1
+
+
+ no
+ ISO-8859-1
+
+
+ pl
+ ISO-8859-2
+
+
+ pt
+ ISO-8859-1
+
+
+ ro
+ ISO-8859-2
+
+
+ ru
+ ISO-8859-5
+
+
+ sh
+ ISO-8859-5
+
+
+ sk
+ ISO-8859-2
+
+
+ sl
+ ISO-8859-2
+
+
+ sq
+ ISO-8859-2
+
+
+ sr
+ ISO-8859-5
+
+
+ sv
+ ISO-8859-1
+
+
+ tr
+ ISO-8859-9
+
+
+ uk
+ ISO-8859-5
+
+
+ zh
+ GB2312
+
+
+ zh_TW
+ Big5
+
+
+
+
+
+ Disable TRACE
+ /
+ TRACE
+
+
+
+
+
+
diff --git a/KeywordSearch/solr/server/lib/ext/disruptor-3.4.2.jar b/KeywordSearch/solr/server/lib/ext/disruptor-3.4.2.jar
new file mode 100755
index 0000000000..b366bbebc5
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/disruptor-3.4.2.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/jcl-over-slf4j-1.7.24.jar b/KeywordSearch/solr/server/lib/ext/jcl-over-slf4j-1.7.24.jar
new file mode 100755
index 0000000000..2ea9e37487
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/jcl-over-slf4j-1.7.24.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/jul-to-slf4j-1.7.24.jar b/KeywordSearch/solr/server/lib/ext/jul-to-slf4j-1.7.24.jar
new file mode 100755
index 0000000000..82f8d17c02
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/jul-to-slf4j-1.7.24.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.11.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.11.2.jar
new file mode 100755
index 0000000000..871e2e121b
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-1.2-api-2.11.2.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/log4j-api-2.11.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-api-2.11.2.jar
new file mode 100755
index 0000000000..809773c0b6
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-api-2.11.2.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/log4j-core-2.11.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-core-2.11.2.jar
new file mode 100755
index 0000000000..dcb652cb79
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-core-2.11.2.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.11.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.11.2.jar
new file mode 100755
index 0000000000..ce8acdaae6
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-slf4j-impl-2.11.2.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/log4j-web-2.11.2.jar b/KeywordSearch/solr/server/lib/ext/log4j-web-2.11.2.jar
new file mode 100755
index 0000000000..e907eddb73
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/log4j-web-2.11.2.jar differ
diff --git a/KeywordSearch/solr/server/lib/ext/slf4j-api-1.7.24.jar b/KeywordSearch/solr/server/lib/ext/slf4j-api-1.7.24.jar
new file mode 100755
index 0000000000..05941a12f0
Binary files /dev/null and b/KeywordSearch/solr/server/lib/ext/slf4j-api-1.7.24.jar differ
diff --git a/KeywordSearch/solr/server/lib/http2-common-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/http2-common-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..0036e2dfd4
Binary files /dev/null and b/KeywordSearch/solr/server/lib/http2-common-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/http2-hpack-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/http2-hpack-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..40ba031490
Binary files /dev/null and b/KeywordSearch/solr/server/lib/http2-hpack-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/http2-server-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/http2-server-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..3ec039f685
Binary files /dev/null and b/KeywordSearch/solr/server/lib/http2-server-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/javax.servlet-api-3.1.0.jar b/KeywordSearch/solr/server/lib/javax.servlet-api-3.1.0.jar
new file mode 100755
index 0000000000..6b14c3d267
Binary files /dev/null and b/KeywordSearch/solr/server/lib/javax.servlet-api-3.1.0.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..25d8729634
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-alpn-java-server-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..6c1d1b838b
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-alpn-server-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-continuation-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-continuation-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..4c6eb054bf
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-continuation-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-deploy-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-deploy-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..6dbd04bb31
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-deploy-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-http-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-http-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..e01b23cf45
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-http-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-io-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-io-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..d21c6da4ee
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-io-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-jmx-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-jmx-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..a97a6f6372
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-jmx-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-rewrite-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-rewrite-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..1b3d3992b7
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-rewrite-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-security-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-security-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..5fc1e2008b
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-security-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-server-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-server-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..7de2211718
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-server-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-servlet-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-servlet-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..9e68e455a3
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-servlet-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-servlets-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-servlets-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..13d97f6728
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-servlets-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-util-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-util-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..5407c94fbe
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-util-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-webapp-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-webapp-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..b63559b825
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-webapp-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/jetty-xml-9.4.19.v20190610.jar b/KeywordSearch/solr/server/lib/jetty-xml-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..26fbeb9367
Binary files /dev/null and b/KeywordSearch/solr/server/lib/jetty-xml-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/lib/metrics-core-4.0.5.jar b/KeywordSearch/solr/server/lib/metrics-core-4.0.5.jar
new file mode 100755
index 0000000000..51a23f4a5c
Binary files /dev/null and b/KeywordSearch/solr/server/lib/metrics-core-4.0.5.jar differ
diff --git a/KeywordSearch/solr/server/lib/metrics-graphite-4.0.5.jar b/KeywordSearch/solr/server/lib/metrics-graphite-4.0.5.jar
new file mode 100755
index 0000000000..a153ce0791
Binary files /dev/null and b/KeywordSearch/solr/server/lib/metrics-graphite-4.0.5.jar differ
diff --git a/KeywordSearch/solr/server/lib/metrics-jetty9-4.0.5.jar b/KeywordSearch/solr/server/lib/metrics-jetty9-4.0.5.jar
new file mode 100755
index 0000000000..c06dc16c0a
Binary files /dev/null and b/KeywordSearch/solr/server/lib/metrics-jetty9-4.0.5.jar differ
diff --git a/KeywordSearch/solr/server/lib/metrics-jmx-4.0.5.jar b/KeywordSearch/solr/server/lib/metrics-jmx-4.0.5.jar
new file mode 100755
index 0000000000..773a83000b
Binary files /dev/null and b/KeywordSearch/solr/server/lib/metrics-jmx-4.0.5.jar differ
diff --git a/KeywordSearch/solr/server/lib/metrics-jvm-4.0.5.jar b/KeywordSearch/solr/server/lib/metrics-jvm-4.0.5.jar
new file mode 100755
index 0000000000..bb296705f7
Binary files /dev/null and b/KeywordSearch/solr/server/lib/metrics-jvm-4.0.5.jar differ
diff --git a/KeywordSearch/solr/server/modules/http.mod b/KeywordSearch/solr/server/modules/http.mod
new file mode 100755
index 0000000000..d4ceec5120
--- /dev/null
+++ b/KeywordSearch/solr/server/modules/http.mod
@@ -0,0 +1,9 @@
+#
+# Jetty HTTP Connector
+#
+
+[depend]
+server
+
+[xml]
+etc/jetty-http.xml
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/modules/https.mod b/KeywordSearch/solr/server/modules/https.mod
new file mode 100755
index 0000000000..8affbcf60f
--- /dev/null
+++ b/KeywordSearch/solr/server/modules/https.mod
@@ -0,0 +1,9 @@
+#
+# Jetty HTTPS Connector
+#
+
+[depend]
+ssl
+
+[xml]
+etc/jetty-https.xml
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/modules/https8.mod b/KeywordSearch/solr/server/modules/https8.mod
new file mode 100755
index 0000000000..f799f6bd0c
--- /dev/null
+++ b/KeywordSearch/solr/server/modules/https8.mod
@@ -0,0 +1,9 @@
+#
+# Jetty HTTPS Connector
+#
+
+[depend]
+ssl
+
+[xml]
+etc/jetty-https8.xml
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/modules/server.mod b/KeywordSearch/solr/server/modules/server.mod
new file mode 100755
index 0000000000..0d60a9e3f4
--- /dev/null
+++ b/KeywordSearch/solr/server/modules/server.mod
@@ -0,0 +1,11 @@
+#
+# Base Server Module
+#
+
+[lib]
+lib/*.jar
+lib/ext/*.jar
+resources/
+
+[xml]
+etc/jetty.xml
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/modules/ssl.mod b/KeywordSearch/solr/server/modules/ssl.mod
new file mode 100755
index 0000000000..091e3dea0d
--- /dev/null
+++ b/KeywordSearch/solr/server/modules/ssl.mod
@@ -0,0 +1,9 @@
+#
+# SSL Keystore module
+#
+
+[depend]
+server
+
+[xml]
+etc/jetty-ssl.xml
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/resources/jetty-logging.properties b/KeywordSearch/solr/server/resources/jetty-logging.properties
new file mode 100755
index 0000000000..55b0c37d34
--- /dev/null
+++ b/KeywordSearch/solr/server/resources/jetty-logging.properties
@@ -0,0 +1 @@
+org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/resources/log4j2-console.xml b/KeywordSearch/solr/server/resources/log4j2-console.xml
new file mode 100755
index 0000000000..e83edf942c
--- /dev/null
+++ b/KeywordSearch/solr/server/resources/log4j2-console.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+ %maxLen{%-5p - %d{yyyy-MM-dd HH:mm:ss.SSS}; %c; %m%notEmpty{ =>%ex{short}}}{10240}%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeywordSearch/solr/server/resources/log4j2.xml b/KeywordSearch/solr/server/resources/log4j2.xml
new file mode 100755
index 0000000000..e76973da64
--- /dev/null
+++ b/KeywordSearch/solr/server/resources/log4j2.xml
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+ %maxLen{%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%notEmpty{ =>%ex{short}}}{10240}%n
+
+
+
+
+
+
+
+ %maxLen{%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%notEmpty{ =>%ex{short}}}{10240}%n
+
+
+
+
+
+
+
+
+
+
+
+
+ %maxLen{%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p (%t) [%X{collection} %X{shard} %X{replica} %X{core}] %c{1.} %m%notEmpty{ =>%ex{short}}}{10240}%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KeywordSearch/solr/server/scripts/cloud-scripts/snapshotscli.sh b/KeywordSearch/solr/server/scripts/cloud-scripts/snapshotscli.sh
new file mode 100755
index 0000000000..e5a26d6457
--- /dev/null
+++ b/KeywordSearch/solr/server/scripts/cloud-scripts/snapshotscli.sh
@@ -0,0 +1,176 @@
+#!/usr/bin/env bash
+
+set -e
+
+run_solr_snapshot_tool() {
+ JVM="java"
+ scriptDir=$(dirname "$0")
+ if [ -n "$LOG4J_PROPS" ]; then
+ log4j_config="file:${LOG4J_PROPS}"
+ else
+ log4j_config="file:${scriptDir}/../../resources/log4j2-console.xml"
+ fi
+ PATH=${JAVA_HOME}/bin:${PATH} ${JVM} ${ZKCLI_JVM_FLAGS} -Dlog4j.configurationFile=${log4j_config} \
+ -classpath "${solrLibPath}" org.apache.solr.core.snapshots.SolrSnapshotsTool "$@" 2> /dev/null
+}
+
+usage() {
+ run_solr_snapshot_tool --help
+}
+
+distcp_warning() {
+ echo "SOLR_USE_DISTCP environment variable is not set. \
+ Do you want to use hadoop distcp tool for exporting Solr collection snapshot ?"
+}
+
+parse_options() {
+ OPTIND=3
+ while getopts ":c:d:s:z:p:r:i:" o ; do
+ case "${o}" in
+ d)
+ destPath=${OPTARG}
+ ;;
+ s)
+ sourcePath=${OPTARG}
+ ;;
+ c)
+ collectionName=${OPTARG}
+ ;;
+ z)
+ solrZkEnsemble=${OPTARG}
+ ;;
+ p)
+ pathPrefix=${OPTARG}
+ ;;
+ r)
+ backupRepoName=${OPTARG}
+ ;;
+ i)
+ aysncReqId=${OPTARG}
+ ;;
+ *)
+ echo "Unknown option ${OPTARG}"
+ usage 1>&2
+ exit 1
+ ;;
+ esac
+ done
+}
+
+prepare_snapshot_export() {
+ #Make sure to cleanup the temporary files.
+ scratch=$(mktemp -d -t solrsnaps.XXXXXXXXXX)
+ function finish {
+ rm -rf "${scratch}"
+ }
+ trap finish EXIT
+
+ if hdfs dfs -test -d "${destPath}" ; then
+ run_solr_snapshot_tool --prepare-snapshot-export "$@" -t "${scratch}"
+
+ hdfs dfs -mkdir -p "${copyListingDirPath}" > /dev/null
+ find "${scratch}" -type f -printf "%f\n" | while read shardId; do
+ echo "Copying the copy-listing for $shardId"
+ hdfs dfs -copyFromLocal "${scratch}/${shardId}" "${copyListingDirPath}" > /dev/null
+ done
+ else
+ echo "Directory ${destPath} does not exist."
+ exit 1
+ fi
+}
+
+copy_snapshot_files() {
+ copylisting_dir_path="$1"
+
+ if hdfs dfs -test -d "${copylisting_dir_path}" ; then
+ for shardId in $(hdfs dfs -stat "%n" "${copylisting_dir_path}/*"); do
+ oPath="${destPath}/${snapshotName}/snapshot.${shardId}"
+ echo "Copying the index files for ${shardId} to ${oPath}"
+ ${distCpCmd} -f "${copylisting_dir_path}/${shardId}" "${oPath}" > /dev/null
+ done
+ else
+ echo "Directory ${copylisting_dir_path} does not exist."
+ exit 1
+ fi
+}
+
+collectionName=""
+solrZkEnsemble=""
+pathPrefix=""
+destPath=""
+sourcePath=""
+cmd="$1"
+snapshotName="$2"
+copyListingDirPath=""
+distCpCmd="${SOLR_DISTCP_CMD:-hadoop distcp}"
+scriptDir=$(dirname "$0")
+solrLibPath="${SOLR_LIB_PATH:-${scriptDir}/../../solr-webapp/webapp/WEB-INF/lib/*:${scriptDir}/../../lib/ext/*}"
+
+case "${cmd}" in
+ --create)
+ run_solr_snapshot_tool "$@"
+ ;;
+ --delete)
+ run_solr_snapshot_tool "$@"
+ ;;
+ --list)
+ run_solr_snapshot_tool "$@"
+ ;;
+ --describe)
+ run_solr_snapshot_tool "$@"
+ ;;
+ --prepare-snapshot-export)
+ : "${SOLR_USE_DISTCP:? $(distcp_warning)}"
+
+ parse_options "$@"
+
+ : "${destPath:? Please specify destination directory using -d option}"
+
+ copyListingDirPath="${destPath}/copylistings"
+ prepare_snapshot_export "${@:2}"
+ echo "Done. GoodBye!"
+ ;;
+ --export)
+ if [ -z "${SOLR_USE_DISTCP}" ]; then
+ run_solr_snapshot_tool "$@"
+ echo "Done. GoodBye!"
+ exit 0
+ fi
+
+ parse_options "$@"
+
+ : "${snapshotName:? Please specify the name of the snapshot}"
+ : "${destPath:? Please specify destination directory using -d option}"
+
+ if [ -n "${collectionName}" ] && [ -n "${sourcePath}" ]; then
+ echo "The -c and -s options can not be specified together"
+ exit 1
+ fi
+
+ if [ -z "${collectionName}" ] && [ -z "${sourcePath}" ]; then
+ echo "At least one of options (-c or -s) must be specified"
+ exit 1
+ fi
+
+ if [ -n "${collectionName}" ]; then
+ copyListingDirPath="${destPath}/${snapshotName}/copylistings"
+ prepare_snapshot_export "${@:2}"
+ copy_snapshot_files "${destPath}/${snapshotName}/copylistings"
+ hdfs dfs -rm -r -f -skipTrash "${destPath}/${snapshotName}/copylistings" > /dev/null
+ else
+ copy_snapshot_files "${sourcePath}/copylistings"
+ echo "Copying the collection meta-data to ${destPath}/${snapshotName}"
+ ${distCpCmd} "${sourcePath}/${snapshotName}/*" "${destPath}/${snapshotName}/" > /dev/null
+ fi
+
+ echo "Done. GoodBye!"
+ ;;
+ --help)
+ usage 1>&2
+ ;;
+ *)
+ echo "Unknown command ${cmd}"
+ usage 1>&2
+ exit 1
+esac
+
diff --git a/KeywordSearch/solr/server/scripts/cloud-scripts/zkcli.bat b/KeywordSearch/solr/server/scripts/cloud-scripts/zkcli.bat
new file mode 100755
index 0000000000..67a1fd4933
--- /dev/null
+++ b/KeywordSearch/solr/server/scripts/cloud-scripts/zkcli.bat
@@ -0,0 +1,25 @@
+@echo off
+REM You can override pass the following parameters to this script:
+REM
+
+set JVM=java
+
+REM Find location of this script
+
+set SDIR=%~dp0
+if "%SDIR:~-1%"=="\" set SDIR=%SDIR:~0,-1%
+
+if defined LOG4J_PROPS (
+ set "LOG4J_CONFIG=file:///%LOG4J_PROPS%"
+) else (
+ set "LOG4J_CONFIG=file:///%SDIR%\..\..\resources\log4j2-console.xml"
+)
+
+REM Settings for ZK ACL
+REM set SOLR_ZK_CREDS_AND_ACLS=-DzkACLProvider=org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider ^
+REM -DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider ^
+REM -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD ^
+REM -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD
+
+"%JVM%" %SOLR_ZK_CREDS_AND_ACLS% %ZKCLI_JVM_FLAGS% -Dlog4j.configurationFile="%LOG4J_CONFIG%" ^
+-classpath "%SDIR%\..\..\solr-webapp\webapp\WEB-INF\lib\*;%SDIR%\..\..\lib\ext\*;%SDIR%\..\..\lib\*" org.apache.solr.cloud.ZkCLI %*
diff --git a/KeywordSearch/solr/server/scripts/cloud-scripts/zkcli.sh b/KeywordSearch/solr/server/scripts/cloud-scripts/zkcli.sh
new file mode 100755
index 0000000000..37b1ec9aa0
--- /dev/null
+++ b/KeywordSearch/solr/server/scripts/cloud-scripts/zkcli.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+# You can override pass the following parameters to this script:
+#
+
+JVM="java"
+
+# Find location of this script
+
+sdir="`dirname \"$0\"`"
+
+if [ -n "$LOG4J_PROPS" ]; then
+ log4j_config="file:$LOG4J_PROPS"
+else
+ log4j_config="file:$sdir/../../resources/log4j2-console.xml"
+fi
+
+# Settings for ZK ACL
+#SOLR_ZK_CREDS_AND_ACLS="-DzkACLProvider=org.apache.solr.common.cloud.VMParamsAllAndReadonlyDigestZkACLProvider \
+# -DzkCredentialsProvider=org.apache.solr.common.cloud.VMParamsSingleSetCredentialsDigestZkCredentialsProvider \
+# -DzkDigestUsername=admin-user -DzkDigestPassword=CHANGEME-ADMIN-PASSWORD \
+# -DzkDigestReadonlyUsername=readonly-user -DzkDigestReadonlyPassword=CHANGEME-READONLY-PASSWORD"
+
+PATH=$JAVA_HOME/bin:$PATH $JVM $SOLR_ZK_CREDS_AND_ACLS $ZKCLI_JVM_FLAGS -Dlog4j.configurationFile=$log4j_config \
+-classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*:$sdir/../../lib/*" org.apache.solr.cloud.ZkCLI ${1+"$@"}
+
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/antlr4-runtime-4.5.1-1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/antlr4-runtime-4.5.1-1.jar
new file mode 100755
index 0000000000..387129d648
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/antlr4-runtime-4.5.1-1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-5.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-5.1.jar
new file mode 100755
index 0000000000..18433c1a22
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-5.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-5.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-5.1.jar
new file mode 100755
index 0000000000..2c8d5b4785
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/asm-commons-5.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.13.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.13.0.jar
new file mode 100755
index 0000000000..a508768422
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/avatica-core-1.13.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.4.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.4.0.jar
new file mode 100755
index 0000000000..80b85190ea
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/caffeine-2.4.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.18.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.18.0.jar
new file mode 100755
index 0000000000..a814080a28
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-core-1.18.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.18.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.18.0.jar
new file mode 100755
index 0000000000..dc5002d5bd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/calcite-linq4j-1.18.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-beanutils-1.9.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-beanutils-1.9.3.jar
new file mode 100755
index 0000000000..6728154e56
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-beanutils-1.9.3.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-cli-1.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-cli-1.2.jar
new file mode 100755
index 0000000000..ce4b9fffe4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-cli-1.2.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-codec-1.11.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-codec-1.11.jar
new file mode 100755
index 0000000000..22451206dd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-codec-1.11.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-collections-3.2.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-collections-3.2.2.jar
new file mode 100755
index 0000000000..fa5df82a63
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-collections-3.2.2.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-compiler-3.0.9.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-compiler-3.0.9.jar
new file mode 100755
index 0000000000..2866a66625
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-compiler-3.0.9.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-configuration2-2.1.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-configuration2-2.1.1.jar
new file mode 100755
index 0000000000..666baa09d2
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-configuration2-2.1.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-exec-1.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-exec-1.3.jar
new file mode 100755
index 0000000000..9a64351981
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-exec-1.3.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-fileupload-1.3.3.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-fileupload-1.3.3.jar
new file mode 100755
index 0000000000..915d87e744
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-fileupload-1.3.3.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.5.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.5.jar
new file mode 100755
index 0000000000..107b061f5f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-io-2.5.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.8.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.8.1.jar
new file mode 100755
index 0000000000..2c65ce67d5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-lang3-3.8.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-math3-3.6.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-math3-3.6.1.jar
new file mode 100755
index 0000000000..0ff582cfcb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-math3-3.6.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-text-1.6.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-text-1.6.jar
new file mode 100755
index 0000000000..63e47300c6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/commons-text-1.6.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-client-2.13.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-client-2.13.0.jar
new file mode 100755
index 0000000000..7c01fbe81e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-client-2.13.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-framework-2.13.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-framework-2.13.0.jar
new file mode 100755
index 0000000000..46cada0777
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-framework-2.13.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-recipes-2.13.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-recipes-2.13.0.jar
new file mode 100755
index 0000000000..caf7b87491
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/curator-recipes-2.13.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/disruptor-3.4.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/disruptor-3.4.2.jar
new file mode 100755
index 0000000000..b366bbebc5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/disruptor-3.4.2.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/eigenbase-properties-1.1.5.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/eigenbase-properties-1.1.5.jar
new file mode 100755
index 0000000000..786c6c6a2b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/eigenbase-properties-1.1.5.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/guava-25.1-jre.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/guava-25.1-jre.jar
new file mode 100755
index 0000000000..babc175535
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/guava-25.1-jre.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.0.jar
new file mode 100755
index 0000000000..0a52d1b6d4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-annotations-3.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.0.jar
new file mode 100755
index 0000000000..683f3f7d1a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-auth-3.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.0.jar
new file mode 100755
index 0000000000..77a00c750c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-common-3.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.0.jar
new file mode 100755
index 0000000000..59afc3eaf6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hadoop-hdfs-client-3.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hppc-0.8.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hppc-0.8.1.jar
new file mode 100755
index 0000000000..39a7c24db6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/hppc-0.8.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/htrace-core4-4.1.0-incubating.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/htrace-core4-4.1.0-incubating.jar
new file mode 100755
index 0000000000..12349a2066
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/htrace-core4-4.1.0-incubating.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..4b86470eaf
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-client-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..0036e2dfd4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-common-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..40ba031490
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-hpack-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..f414c53fed
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/http2-http-client-transport-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.6.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.6.jar
new file mode 100755
index 0000000000..56231de0cb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpclient-4.5.6.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.10.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.10.jar
new file mode 100755
index 0000000000..dc510f81cb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpcore-4.4.10.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.6.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.6.jar
new file mode 100755
index 0000000000..df5a7d195f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/httpmime-4.5.6.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.9.8.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.9.8.jar
new file mode 100755
index 0000000000..4d9f421537
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-annotations-2.9.8.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.9.8.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.9.8.jar
new file mode 100755
index 0000000000..362f1f393e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-core-2.9.8.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.9.8.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.9.8.jar
new file mode 100755
index 0000000000..2d8687b5d7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-databind-2.9.8.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.9.8.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.9.8.jar
new file mode 100755
index 0000000000..ba565e5874
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jackson-dataformat-smile-2.9.8.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/janino-3.0.9.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/janino-3.0.9.jar
new file mode 100755
index 0000000000..761e0c2a0a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/janino-3.0.9.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..86593a3225
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-client-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..33053ee72a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-alpn-java-client-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..4699df44ba
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-client-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..e01b23cf45
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-http-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..d21c6da4ee
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-io-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.19.v20190610.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.19.v20190610.jar
new file mode 100755
index 0000000000..5407c94fbe
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jetty-util-9.4.19.v20190610.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jose4j-0.6.5.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jose4j-0.6.5.jar
new file mode 100755
index 0000000000..02c0a5a66c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/jose4j-0.6.5.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/json-path-2.4.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/json-path-2.4.0.jar
new file mode 100755
index 0000000000..6229306b85
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/json-path-2.4.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerb-core-1.0.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerb-core-1.0.1.jar
new file mode 100755
index 0000000000..655c87a627
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerb-core-1.0.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerb-util-1.0.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerb-util-1.0.1.jar
new file mode 100755
index 0000000000..8b9b244505
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerb-util-1.0.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerby-asn1-1.0.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerby-asn1-1.0.1.jar
new file mode 100755
index 0000000000..6488b7462b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerby-asn1-1.0.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerby-pkix-1.0.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerby-pkix-1.0.1.jar
new file mode 100755
index 0000000000..443d981891
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/kerby-pkix-1.0.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.2.0.jar
new file mode 100755
index 0000000000..92a1a6e6e0
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-common-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.2.0.jar
new file mode 100755
index 0000000000..7c48ec507e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-kuromoji-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.2.0.jar
new file mode 100755
index 0000000000..21a6e1a800
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-nori-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.2.0.jar
new file mode 100755
index 0000000000..6bbf7b43a6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analyzers-phonetic-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.2.0.jar
new file mode 100755
index 0000000000..597024cb81
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-backward-codecs-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.2.0.jar
new file mode 100755
index 0000000000..51680e713c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-classification-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.2.0.jar
new file mode 100755
index 0000000000..d88e69df0f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-codecs-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.2.0.jar
new file mode 100755
index 0000000000..a643eecacf
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.2.0.jar
new file mode 100755
index 0000000000..3f93fbc864
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-expressions-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.2.0.jar
new file mode 100755
index 0000000000..0d93db62eb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-grouping-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.2.0.jar
new file mode 100755
index 0000000000..24ab281410
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-highlighter-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.2.0.jar
new file mode 100755
index 0000000000..20937f03a7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-join-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.2.0.jar
new file mode 100755
index 0000000000..e62f273752
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-memory-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.2.0.jar
new file mode 100755
index 0000000000..bef175c46f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-misc-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.2.0.jar
new file mode 100755
index 0000000000..87965f7f86
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.2.0.jar
new file mode 100755
index 0000000000..49a8294e08
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.2.0.jar
new file mode 100755
index 0000000000..66976e2160
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-sandbox-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.2.0.jar
new file mode 100755
index 0000000000..f0e716ab5d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial-extras-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.2.0.jar
new file mode 100755
index 0000000000..937f288016
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-spatial3d-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.2.0.jar
new file mode 100755
index 0000000000..2b3dd10bc4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-suggest-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-api-0.33.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-api-0.33.0.jar
new file mode 100755
index 0000000000..e3d65567d7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-api-0.33.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-noop-0.33.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-noop-0.33.0.jar
new file mode 100755
index 0000000000..f5101f8596
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-noop-0.33.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-util-0.33.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-util-0.33.0.jar
new file mode 100755
index 0000000000..5e5e2e1fa8
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/opentracing-util-0.33.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet-2.3.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet-2.3.0.jar
new file mode 100755
index 0000000000..64549e4980
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet-2.3.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet.ext.servlet-2.3.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet.ext.servlet-2.3.0.jar
new file mode 100755
index 0000000000..58a884ab9c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/org.restlet.ext.servlet-2.3.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/protobuf-java-3.6.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/protobuf-java-3.6.1.jar
new file mode 100755
index 0000000000..8a187891fc
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/protobuf-java-3.6.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/re2j-1.2.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/re2j-1.2.jar
new file mode 100755
index 0000000000..945db1ca03
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/re2j-1.2.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/rrd4j-3.5.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/rrd4j-3.5.jar
new file mode 100755
index 0000000000..535ea8fbea
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/rrd4j-3.5.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/s2-geometry-library-java-1.0.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/s2-geometry-library-java-1.0.0.jar
new file mode 100755
index 0000000000..87638c0757
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/s2-geometry-library-java-1.0.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.2.0.jar
new file mode 100755
index 0000000000..e70d5e88d0
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-core-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.2.0.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.2.0.jar
new file mode 100755
index 0000000000..b357a80cdf
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-8.2.0.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/spatial4j-0.7.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/spatial4j-0.7.jar
new file mode 100755
index 0000000000..feb2e02aa1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/spatial4j-0.7.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-3.1.4.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-3.1.4.jar
new file mode 100755
index 0000000000..dded036928
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/stax2-api-3.1.4.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/t-digest-3.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/t-digest-3.1.jar
new file mode 100755
index 0000000000..a638007a87
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/t-digest-3.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-asl-4.4.1.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-asl-4.4.1.jar
new file mode 100755
index 0000000000..d8b4e8cf87
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/woodstox-core-asl-4.4.1.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.5.5.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.5.5.jar
new file mode 100755
index 0000000000..bf5fb88da6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-3.5.5.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.5.5.jar b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.5.5.jar
new file mode 100755
index 0000000000..ae72aca1f2
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/lib/zookeeper-jute-3.5.5.jar differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/web.xml b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/web.xml
new file mode 100755
index 0000000000..53ab57abbb
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/WEB-INF/web.xml
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+ SolrRequestFilter
+ org.apache.solr.servlet.SolrDispatchFilter
+
+
+ excludePatterns
+ /partials/.+,/libs/.+,/css/.+,/js/.+,/img/.+,/templates/.+
+
+
+
+
+ SolrRequestFilter
+ /*
+
+
+
+ LoadAdminUI
+ org.apache.solr.servlet.LoadAdminUiServlet
+
+
+
+ SolrRestApi
+ org.restlet.ext.servlet.ServerServlet
+
+ org.restlet.application
+ org.apache.solr.rest.SolrSchemaRestApi
+
+
+
+
+ LoadAdminUI
+ /index.html
+
+
+
+ SolrRestApi
+ /schema/*
+
+
+
+ .xsl
+
+ application/xslt+xml
+
+
+
+ index.html
+
+
+
+
+
+ Disable TRACE
+ /
+ TRACE
+
+
+
+
+
+ Enable everything but TRACE
+ /
+ TRACE
+
+
+
+
+
+
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/analysis.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/analysis.css
new file mode 100755
index 0000000000..1cbff55ed2
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/analysis.css
@@ -0,0 +1,303 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #analysis-holder
+{
+ background-image: url( ../../img/div.gif );
+ background-position: 50% 0;
+ background-repeat: repeat-y;
+}
+
+#content #analysis #field-analysis
+{
+ margin-bottom: 0;
+}
+
+#content #analysis #field-analysis .content
+{
+ padding-bottom: 0;
+}
+
+#content #analysis .settings-holder
+{
+ clear: both;
+ padding-top: 15px;
+}
+
+#content #analysis .settings
+{
+ background-color: #fff;
+ border-top: 1px solid #fafafa;
+ border-bottom: 1px solid #fafafa;
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+#content #analysis .settings select.loader
+{
+ background-position: 3px 50%;
+ padding-left: 21px;
+}
+
+#content #analysis .settings select optgroup
+{
+ font-style: normal;
+ padding: 5px;
+}
+
+#content #analysis .settings select option
+{
+ padding-left: 10px;
+}
+
+#content #analysis .settings #tor_schema
+{
+ background-image: url( ../../img/ico/question-white.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ margin-left: 5px;
+ padding-left: 21px;
+}
+
+#content #analysis .settings #tor_schema:hover
+{
+ background-image: url( ../../img/ico/question.png );
+}
+
+#content #analysis .settings #tor_schema span
+{
+/* display: none; */
+}
+
+#content #analysis .settings #tor_schema:hover span
+{
+ display: inline;
+}
+
+#content #analysis .settings .buttons
+{
+ float: right;
+ width: 47%;
+}
+
+#content #analysis .settings button
+{
+ float: right;
+}
+
+#content #analysis .settings button span
+{
+ background-image: url( ../../img/ico/funnel.png );
+}
+
+#content #analysis .settings .verbose_output
+{
+ float: left;
+ width: auto;
+}
+
+#content #analysis .settings .verbose_output a
+{
+ background-image: url( ../../img/ico/ui-check-box-uncheck.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ display: block;
+ padding-left: 21px;
+}
+
+#content #analysis .settings .verbose_output.active a
+{
+ background-image: url( ../../img/ico/ui-check-box.png );
+}
+
+#content #analysis .index label,
+#content #analysis .query label
+{
+ display: block;
+}
+
+#content #analysis .index textarea,
+#content #analysis .query textarea
+{
+ display: block;
+ width: 100%;
+}
+
+#content #analysis .index
+{
+ float: left;
+ margin-right: 0.5%;
+ min-width: 47%;
+ max-width: 99%;
+}
+
+#content #analysis .query
+{
+ float: right;
+ margin-left: 0.5%;
+ min-width: 47%;
+ max-width: 99%;
+}
+
+#content #analysis .analysis-error
+{
+ background-color: #f00;
+ background-image: url( ../../img/ico/construction.png );
+ background-position: 10px 50%;
+ color: #fff;
+ font-weight: bold;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+}
+
+#content #analysis .analysis-error .head a
+{
+ color: #fff;
+ cursor: auto;
+}
+
+#content #analysis #analysis-result
+{
+ overflow: auto;
+}
+
+#content #analysis #analysis-result .index,
+#content #analysis #analysis-result .query
+{
+ background-color: #fff;
+ padding-top: 20px;
+}
+
+#content #analysis #analysis-result table
+{
+ border-collapse: collapse;
+}
+
+#content #analysis #analysis-result td
+{
+ vertical-align: top;
+ white-space: nowrap;
+}
+
+#content #analysis #analysis-result td.part.analyzer div,
+#content #analysis #analysis-result td.part.spacer .holder,
+#content #analysis #analysis-result td td td
+{
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
+#content #analysis #analysis-result.verbose_output td.legend
+{
+ display: table-cell;
+}
+
+#content #analysis #analysis-result.verbose_output td.data tr.verbose_output
+{
+ display: table-row;
+}
+
+#content #analysis #analysis-result .match
+{
+ background-color: #F0D9C3;
+}
+
+#content #analysis #analysis-result td.part
+{
+ padding-bottom: 10px;
+}
+
+#content #analysis #analysis-result td.part.analyzer div
+{
+ border-right: 1px solid #f0f0f0;
+ padding-right: 10px;
+}
+
+#content #analysis #analysis-result td.part.analyzer abbr
+{
+ color: #4D4D4D;
+}
+
+#content #analysis #analysis-result td.part.legend .holder,
+#content #analysis #analysis-result td.part.data .holder
+{
+ padding-left: 10px;
+ padding-right: 10px;
+ border-right: 1px solid #c0c0c0;
+}
+
+#content #analysis #analysis-result td.part.legend td
+{
+ color: #4D4D4D;
+}
+
+#content #analysis #analysis-result td.part.legend .holder
+{
+ border-right-color: #f0f0f0;
+}
+
+#content #analysis #analysis-result td.part.data:last-child .holder
+{
+ padding-right: 0;
+ border-right: 0;
+}
+
+#content #analysis #analysis-result td.details
+{
+ padding-left: 10px;
+ padding-right: 10px;
+ border-left: 1px solid #f0f0f0;
+ border-right: 1px solid #f0f0f0;
+}
+
+#content #analysis #analysis-result td.details:first-child
+{
+ padding-left: 0;
+ border-left: 0;
+}
+
+#content #analysis #analysis-result td.details:last-child
+{
+ padding-right: 0;
+ border-right: 0;
+}
+
+#content #analysis #analysis-result td.details tr.empty td
+{
+ color: #f0f0f0;
+}
+
+#content #analysis #analysis-result td.details tr.raw_bytes td
+{
+ letter-spacing: -1px;
+}
+
+#content #analysis #analysis-result .part table table td
+{
+ border-top: 1px solid #f0f0f0;
+}
+
+#content #analysis #analysis-result .part table table tr:first-child td
+{
+ border-top: 0;
+}
+
+#content #analysis #field-analysis h2 { background-image: url( ../../img/ico/receipt.png ); }
+#content #analysis .analysis-result h2 { background-image: url( ../../img/ico/receipt-invoice.png ); }
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/chosen.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/chosen.css
new file mode 100755
index 0000000000..f7ae771216
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/chosen.css
@@ -0,0 +1,465 @@
+/*
+
+Chosen
+
+- by Patrick Filler for Harvest http://getharvest.com
+- Copyright (c) 2011-2013 by Harvest
+
+Available for use under the MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+/*!
+Chosen, a Select Box Enhancer for jQuery and Prototype
+by Patrick Filler for Harvest, http://getharvest.com
+
+Version 1.3.0
+Full source at https://github.com/harvesthq/chosen
+Copyright (c) 2011-2014 Harvest http://getharvest.com
+
+MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
+This file is generated by `grunt build`, do not edit it by hand.
+*/
+
+/* @group Base */
+.chosen-container {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 13px;
+ zoom: 1;
+ *display: inline;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+.chosen-container * {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.chosen-container .chosen-drop {
+ position: absolute;
+ top: 100%;
+ left: -9999px;
+ z-index: 1010;
+ width: 100%;
+ border: 1px solid #aaa;
+ border-top: 0;
+ background: #fff;
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
+}
+.chosen-container.chosen-with-drop .chosen-drop {
+ left: 0;
+}
+.chosen-container a {
+ cursor: pointer;
+}
+
+/* @end */
+/* @group Single Chosen */
+.chosen-container-single .chosen-single {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ padding: 0 0 0 8px;
+ height: 25px;
+ border: 1px solid #aaa;
+ border-radius: 5px;
+ background-color: #fff;
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
+ background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background-clip: padding-box;
+ box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
+ color: #444;
+ text-decoration: none;
+ white-space: nowrap;
+ line-height: 24px;
+}
+.chosen-container-single .chosen-default {
+ color: #999;
+}
+.chosen-container-single .chosen-single span {
+ display: block;
+ overflow: hidden;
+ margin-right: 26px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.chosen-container-single .chosen-single-with-deselect span {
+ margin-right: 38px;
+}
+.chosen-container-single .chosen-single abbr {
+ position: absolute;
+ top: 6px;
+ right: 26px;
+ display: block;
+ width: 12px;
+ height: 12px;
+ background: url('../../img/chosen-sprite.png') -42px 1px no-repeat;
+ font-size: 1px;
+}
+.chosen-container-single .chosen-single abbr:hover {
+ background-position: -42px -10px;
+}
+.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
+ background-position: -42px -10px;
+}
+.chosen-container-single .chosen-single div {
+ position: absolute;
+ top: 0;
+ right: 0;
+ display: block;
+ width: 18px;
+ height: 100%;
+}
+.chosen-container-single .chosen-single div b {
+ display: block;
+ width: 100%;
+ height: 100%;
+ background: url('../../img/chosen-sprite.png') no-repeat 0px 2px;
+}
+.chosen-container-single .chosen-search {
+ position: relative;
+ z-index: 1010;
+ margin: 0;
+ padding: 3px 4px;
+ white-space: nowrap;
+}
+.chosen-container-single .chosen-search input[type="text"] {
+ margin: 1px 0;
+ padding: 4px 20px 4px 5px;
+ width: 100%;
+ height: auto;
+ outline: 0;
+ border: 1px solid #aaa;
+ background: white url('../../img/chosen-sprite.png') no-repeat 100% -20px;
+ background: url('../../img/chosen-sprite.png') no-repeat 100% -20px;
+ font-size: 1em;
+ font-family: sans-serif;
+ line-height: normal;
+ border-radius: 0;
+}
+.chosen-container-single .chosen-drop {
+ margin-top: -1px;
+ border-radius: 0 0 4px 4px;
+ background-clip: padding-box;
+}
+.chosen-container-single.chosen-container-single-nosearch .chosen-search {
+ position: absolute;
+ left: -9999px;
+}
+
+/* @end */
+/* @group Results */
+.chosen-container .chosen-results {
+ color: #444;
+ position: relative;
+ overflow-x: hidden;
+ overflow-y: auto;
+ margin: 0 4px 4px 0;
+ padding: 0 0 0 4px;
+ max-height: 240px;
+ -webkit-overflow-scrolling: touch;
+}
+.chosen-container .chosen-results li {
+ display: none;
+ margin: 0;
+ padding: 5px 6px;
+ list-style: none;
+ line-height: 15px;
+ word-wrap: break-word;
+ -webkit-touch-callout: none;
+}
+.chosen-container .chosen-results li.active-result {
+ display: list-item;
+ cursor: pointer;
+}
+.chosen-container .chosen-results li.disabled-result {
+ display: list-item;
+ color: #ccc;
+ cursor: default;
+}
+.chosen-container .chosen-results li.highlighted {
+ background-color: #3875d7;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
+ background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
+ background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
+ background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
+ background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
+ color: #fff;
+}
+.chosen-container .chosen-results li.no-results {
+ color: #777;
+ display: list-item;
+ background: #f4f4f4;
+}
+.chosen-container .chosen-results li.group-result {
+ display: list-item;
+ font-weight: bold;
+ cursor: default;
+}
+.chosen-container .chosen-results li.group-option {
+ padding-left: 15px;
+}
+.chosen-container .chosen-results li em {
+ font-style: normal;
+ text-decoration: underline;
+}
+
+/* @end */
+/* @group Multi Chosen */
+.chosen-container-multi .chosen-choices {
+ position: relative;
+ overflow: hidden;
+ margin: 0;
+ padding: 0 5px;
+ width: 100%;
+ height: auto !important;
+ height: 1%;
+ border: 1px solid #aaa;
+ background-color: #fff;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
+ background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
+ background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
+ background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
+ background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
+ cursor: text;
+}
+.chosen-container-multi .chosen-choices li {
+ float: left;
+ list-style: none;
+}
+.chosen-container-multi .chosen-choices li.search-field {
+ margin: 0;
+ padding: 0;
+ white-space: nowrap;
+}
+.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
+ margin: 1px 0;
+ padding: 0;
+ height: 25px;
+ outline: 0;
+ border: 0 !important;
+ background: transparent !important;
+ box-shadow: none;
+ color: #999;
+ font-size: 100%;
+ font-family: sans-serif;
+ line-height: normal;
+ border-radius: 0;
+}
+.chosen-container-multi .chosen-choices li.search-choice {
+ position: relative;
+ margin: 3px 5px 3px 0;
+ padding: 3px 20px 3px 5px;
+ border: 1px solid #aaa;
+ max-width: 100%;
+ border-radius: 3px;
+ background-color: #eeeeee;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+ background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-size: 100% 19px;
+ background-repeat: repeat-x;
+ background-clip: padding-box;
+ box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+ color: #333;
+ line-height: 13px;
+ cursor: default;
+}
+.chosen-container-multi .chosen-choices li.search-choice span {
+ word-wrap: break-word;
+}
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
+ position: absolute;
+ top: 4px;
+ right: 3px;
+ display: block;
+ width: 12px;
+ height: 12px;
+ background: url('../../img/chosen-sprite.png') -42px 1px no-repeat;
+ font-size: 1px;
+}
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
+ background-position: -42px -10px;
+}
+.chosen-container-multi .chosen-choices li.search-choice-disabled {
+ padding-right: 5px;
+ border: 1px solid #ccc;
+ background-color: #e4e4e4;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ color: #666;
+}
+.chosen-container-multi .chosen-choices li.search-choice-focus {
+ background: #d4d4d4;
+}
+.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
+ background-position: -42px -10px;
+}
+.chosen-container-multi .chosen-results {
+ margin: 0;
+ padding: 0;
+}
+.chosen-container-multi .chosen-drop .result-selected {
+ display: list-item;
+ color: #ccc;
+ cursor: default;
+}
+
+/* @end */
+/* @group Active */
+.chosen-container-active .chosen-single {
+ border: 1px solid #5897fb;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+}
+.chosen-container-active.chosen-with-drop .chosen-single {
+ border: 1px solid #aaa;
+ -moz-border-radius-bottomright: 0;
+ border-bottom-right-radius: 0;
+ -moz-border-radius-bottomleft: 0;
+ border-bottom-left-radius: 0;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
+ background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
+ background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
+ background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
+ background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
+ box-shadow: 0 1px 0 #fff inset;
+}
+.chosen-container-active.chosen-with-drop .chosen-single div {
+ border-left: none;
+ background: transparent;
+}
+.chosen-container-active.chosen-with-drop .chosen-single div b {
+ background-position: -18px 2px;
+}
+.chosen-container-active .chosen-choices {
+ border: 1px solid #5897fb;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+}
+.chosen-container-active .chosen-choices li.search-field input[type="text"] {
+ color: #222 !important;
+}
+
+/* @end */
+/* @group Disabled Support */
+.chosen-disabled {
+ opacity: 0.5 !important;
+ cursor: default;
+}
+.chosen-disabled .chosen-single {
+ cursor: default;
+}
+.chosen-disabled .chosen-choices .search-choice .search-choice-close {
+ cursor: default;
+}
+
+/* @end */
+/* @group Right to Left */
+.chosen-rtl {
+ text-align: right;
+}
+.chosen-rtl .chosen-single {
+ overflow: visible;
+ padding: 0 8px 0 0;
+}
+.chosen-rtl .chosen-single span {
+ margin-right: 0;
+ margin-left: 26px;
+ direction: rtl;
+}
+.chosen-rtl .chosen-single-with-deselect span {
+ margin-left: 38px;
+}
+.chosen-rtl .chosen-single div {
+ right: auto;
+ left: 3px;
+}
+.chosen-rtl .chosen-single abbr {
+ right: auto;
+ left: 26px;
+}
+.chosen-rtl .chosen-choices li {
+ float: right;
+}
+.chosen-rtl .chosen-choices li.search-field input[type="text"] {
+ direction: rtl;
+}
+.chosen-rtl .chosen-choices li.search-choice {
+ margin: 3px 5px 3px 0;
+ padding: 3px 5px 3px 19px;
+}
+.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
+ right: auto;
+ left: 4px;
+}
+.chosen-rtl.chosen-container-single-nosearch .chosen-search,
+.chosen-rtl .chosen-drop {
+ left: 9999px;
+}
+.chosen-rtl.chosen-container-single .chosen-results {
+ margin: 0 0 4px 4px;
+ padding: 0 4px 0 0;
+}
+.chosen-rtl .chosen-results li.group-option {
+ padding-right: 15px;
+ padding-left: 0;
+}
+.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
+ border-right: none;
+}
+.chosen-rtl .chosen-search input[type="text"] {
+ padding: 4px 5px 4px 20px;
+ background: white url('../../img/chosen-sprite.png') no-repeat -30px -20px;
+ background: url('../../img/chosen-sprite.png') no-repeat -30px -20px;
+ direction: rtl;
+}
+.chosen-rtl.chosen-container-single .chosen-single div b {
+ background-position: 6px 2px;
+}
+.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
+ background-position: -12px 2px;
+}
+
+/* @end */
+/* @group Retina compatibility */
+@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
+ .chosen-rtl .chosen-search input[type="text"],
+ .chosen-container-single .chosen-single abbr,
+ .chosen-container-single .chosen-single div b,
+ .chosen-container-single .chosen-search input[type="text"],
+ .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
+ .chosen-container .chosen-results-scroll-down span,
+ .chosen-container .chosen-results-scroll-up span {
+ background-image: url('../../img/chosen-sprite-2x.png') !important;
+ background-size: 52px 37px !important;
+ background-repeat: no-repeat !important;
+ }
+}
+/* @end */
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/cloud.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/cloud.css
new file mode 100755
index 0000000000..c702c7a1db
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/cloud.css
@@ -0,0 +1,722 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #cloud
+{
+ position: relative;
+}
+
+#content #cloud .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #cloud #error
+{
+ background-color: #f00;
+ background-image: url( ../../img/ico/construction.png );
+ background-position: 10px 12px;
+ color: #fff;
+ font-weight: bold;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+}
+
+#content #cloud #error .msg
+{
+ font-style: italic;
+ font-weight: normal;
+ margin-top: 10px;
+}
+
+#content #cloud #debug
+{
+ background-color: #fff;
+ box-shadow: 0px 0px 10px #c0c0c0;
+ -moz-box-shadow: 0px 0px 10px #c0c0c0;
+ -webkit-box-shadow: 0px 0px 10px #c0c0c0;
+ padding: 20px;
+ position: absolute;
+ left: 50px;
+ top: 10px;
+}
+
+#content #cloud #debug ul
+{
+ margin-bottom: 5px;
+}
+
+#content #cloud #debug ul a
+{
+ background-position: 4px 50%;
+ border-right: 0;
+ display: block;
+ padding: 2px 4px;
+ padding-left: 25px;
+}
+
+#content #cloud #debug ul a:hover,
+#content #cloud #debug ul a.hover
+{
+ background-color: #f0f0f0;
+}
+
+#content #cloud #debug .clipboard
+{
+ float: left;
+ position: relative;
+}
+
+#content #cloud #debug .clipboard a
+{
+ background-image: url( ../../img/ico/clipboard-paste.png );
+ z-index: 98;
+}
+
+#content #cloud #debug .clipboard a:hover,
+#content #cloud #debug .clipboard a.hover,
+#content #cloud #debug .clipboard.copied a
+{
+ background-image: url( ../../img/ico/clipboard-paste-document-text.png );
+}
+
+#content #cloud #debug .close
+{
+ float: right;
+}
+
+#content #cloud #debug .close a
+{
+ background-image: url( ../../img/ico/cross-0.png );
+ padding-left: 21px;
+}
+
+#content #cloud #debug .close a:hover
+{
+ background-image: url( ../../img/ico/cross-1.png );
+}
+
+#content #cloud #debug .debug
+{
+ border: 1px solid #f0f0f0;
+ max-height: 350px;
+ overflow: auto;
+ padding: 5px;
+ width: 500px;
+}
+
+#content #cloud #debug .debug .loader
+{
+ background-position: 5px 50%;
+ display: block;
+ padding: 10px 26px;
+}
+
+#content #cloud .content
+{
+ padding-left: 0;
+ padding-right: 0;
+}
+
+#content #cloud .content.show
+{
+ background-image: url( ../../img/div.gif );
+ background-repeat: repeat-y;
+ background-position: 31% 0;
+}
+
+#content #cloud #tree
+{
+ float: left;
+ width: 30%;
+}
+
+#content #cloud .show #tree
+{
+ overflow: hidden;
+}
+
+#content #cloud #file-content
+{
+ float: right;
+ position: relative;
+ width: 68%;
+ min-height: 100px
+}
+
+#content #cloud .show #file-content
+{
+ display: block;
+}
+
+#content #cloud #file-content .close
+{
+ background-image: url( ../../img/ico/cross-0.png );
+ background-position: 50% 50%;
+ display: block;
+ height: 20px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 20px;
+}
+
+#content #cloud #file-content .close:hover
+{
+ background-image: url( ../../img/ico/cross-1.png );
+}
+
+#content #cloud #file-content #toggle.plus
+{
+ font-style: italic;
+ padding-left: 17px;
+ background-image: url( ../../img/ico/toggle-small-expand.png );
+}
+
+#content #cloud #file-content #toggle.minus
+{
+ font-style: italic;
+ padding-left: 17px;
+ background-image: url( ../../img/ico/toggle-small.png );
+}
+
+#content #cloud #file-content #data
+{
+ border-top: 1px solid #c0c0c0;
+ margin-top: 10px;
+ padding-top: 10px;
+}
+
+#content #cloud #file-content #data pre
+{
+ display: block;
+ max-height: 600px;
+ overflow: auto;
+}
+
+#content #cloud #file-content #data em
+{
+ color: #4d4d4d;
+}
+
+#content #cloud #file-content #prop
+{
+}
+
+#content #cloud #file-content li
+{
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+#content #cloud #file-content li.odd
+{
+ background-color: #F8F8F8;
+}
+
+#content #cloud #file-content li dt
+{
+ float: left;
+ width: 19%;
+}
+
+#content #cloud #file-content li dd
+{
+ float: right;
+ width: 80%;
+}
+
+/* tree */
+
+#content #cloud #legend
+{
+ border: 1px solid #f0f0f0;
+ padding: 10px;
+ position: absolute;
+ right: 0;
+ bottom: 0;
+}
+
+#content #cloud #legend li
+{
+ padding-left: 15px;
+ position: relative;
+}
+
+#content #cloud #legend li svg
+{
+ position: absolute;
+ left: 0;
+ top: 2px;
+}
+
+#content #graph-content
+{
+ min-height: 400px;
+}
+
+#content #graph-content .node
+{
+ fill: #333;
+}
+
+#content #cloud #legend circle,
+#content #graph-content .node circle
+{
+ fill: #fff;
+ stroke: #c0c0c0;
+ stroke-width: 1.5px;
+}
+
+#content #graph-content .node.lvl-3 text
+{
+ cursor: pointer;
+}
+
+#content #graph-content .node.lvl-3:hover circle
+{
+ stroke: #000 !important;
+}
+
+#content #graph-content .node.lvl-3:hover text
+{
+ fill: #000 !important;
+}
+
+#content #graph-content .link
+{
+ fill: none;
+ stroke: #e0e0e0;
+ stroke-width: 1.5px;
+}
+
+#content #cloud #legend .gone circle,
+#content #graph-content .node.gone circle,
+#content #graph-content .link.gone
+{
+ stroke: #f0f0f0;
+}
+
+#content #graph-content .node.gone text
+{
+ fill: #f0f0f0;
+}
+
+#content #cloud #legend ul .gone
+{
+ color: #e0e0e0;
+}
+
+#content #cloud #legend .recovery_failed,
+#content #cloud #legend .recovery_failed circle,
+#content #graph-content .node.recovery_failed circle
+{
+ color: #C43C35;
+ stroke: #C43C35;
+ font-style: italic;
+}
+
+#content #graph-content .node.recovery_failed text
+{
+ fill: #C43C35;
+ font-style: italic;
+}
+
+#content #cloud #legend .down,
+#content #cloud #legend .down circle,
+#content #graph-content .node.down circle
+{
+ color: #c48f00;
+ stroke: #c48f00;
+}
+
+#content #graph-content .node.down text
+{
+ fill: #c48f00;
+}
+
+#content #cloud #legend .recovering,
+#content #cloud #legend .recovering circle,
+#content #graph-content .node.recovering circle
+{
+ color: #d5dd00;
+ stroke: #d5dd00;
+ font-style: italic;
+}
+
+#content #graph-content .node.recovering text
+{
+ fill: #d5dd00;
+ font-style: italic;
+}
+
+#content #cloud #legend .active,
+#content #cloud #legend .active circle,
+#content #graph-content .node.active circle
+{
+ color: #57A957;
+ stroke: #57A957;
+}
+
+#content #graph-content .node.active text
+{
+ fill: #57A957;
+}
+
+#content #cloud #legend .leader circle,
+#content #graph-content .node.leader circle
+{
+ fill: #000;
+}
+
+#content #cloud #legend .leader circle
+{
+ stroke: #fff;
+}
+
+#content #graph-content .link.lvl-2,
+#content #graph-content .link.leader
+{
+ stroke: #c0c0c0;
+}
+
+#content #cloud #legend .leader,
+#content #graph-content .leader text
+{
+ font-weight: bold;
+}
+
+#content #graph-content .node.lvl-0 circle
+{
+ stroke: #fff;
+}
+
+#content #graph-content .link.lvl-1
+{
+ stroke: #fff;
+}
+
+#cloudGraphPaging
+{
+ display: inline-block;
+ padding-top: 15px;
+ padding-bottom: 15px;
+}
+
+#nodesPaging
+{
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+#content #cloud #legend .shard-inactive,
+#content #cloud #legend .shard-inactive li,
+#content #cloud #legend .shard-inactive li text,
+#content #graph-content .shard-inactive text
+{
+ text-decoration: line-through;
+}
+#content #cloud #legend .shard-inactive circle,
+#content #graph-content .shard-inactive circle,
+#content #graph-content .link.shard-inactive
+{
+ stroke: #e9e9e9;
+}
+
+#content #cloud #legend .replicatype,
+#content #cloud #legend .replicatype rect,
+#content #graph-content .node.replicatype rect
+{
+ color: #007BA7;
+ stroke: #007BA7;
+ fill:rgb(0,123,167);
+
+}
+
+#content #graph-content .node.replicatype text
+{
+ fill: #007BA7;
+}
+
+/* Nodes tab */
+#nodes-table {
+ border-collapse: collapse;
+}
+
+#nodes-table td, #nodes-table th {
+ border: 1px solid #ddd;
+ padding: 8px;
+ vertical-align: top;
+}
+#nodes-table th {
+ font-weight: bolder;
+ font-stretch: extra-expanded;
+ background: #F8F8F8;
+}
+#content #cloud #nodes-content #nodes-table
+{
+ border-top: 1px solid #c0c0c0;
+ margin-top: 10px;
+ padding-top: 10px;
+}
+
+#content #cloud #nodes-content .host-name,
+#content #cloud #nodes-content .node-name a
+{
+ font-weight: bold;
+ font-size: larger;
+}
+
+#content #cloud #nodes-content a,
+#content #cloud #nodes-content a:hover,
+#content #cloud #nodes-content a.hover
+{
+ text-decoration: underline;
+ text-decoration-style: dotted;
+ text-decoration-color: #beebff;
+}
+
+#content #cloud #nodes-content a:hover,
+#content #cloud #nodes-content a.hover
+{
+ background-color: #beebff;
+}
+
+#content #cloud #nodes-content .host-spec,
+#content #cloud #nodes-content .node-spec,
+#content #cloud #nodes-content .node-spec a
+{
+ font-style: italic;
+}
+#content #cloud #nodes-content .node-uptime
+{
+ font-weight: bolder;
+ font-size: 20px;
+}
+#content #cloud #nodes-content .node-load,
+#content #cloud #nodes-content .node-cpu,
+#content #cloud #nodes-content .node-heap,
+#content #cloud #nodes-content .node-disk
+{
+ font-weight: bolder;
+ font-size: 20px;
+}
+
+#content #cloud #nodes-content .pct-normal
+{
+ color: darkgreen;
+}
+
+#content #cloud #nodes-content .pct-warn
+{
+ color: orange;
+}
+
+#content #cloud #nodes-content .pct-critical
+{
+ color: red;
+}
+
+#content #cloud #nodes-content .node-down
+{
+ font-weight: bold;
+ font-size: 12px;
+}
+
+#content #cloud #nodes-content .dead-node
+{
+ background-color: salmon;
+}
+
+/* Styling of reload and details buttons */
+#content #cloud #controls,
+#content #cloud #frame #zk-status-content #zk-controls
+{
+ display: block;
+ height: 30px;
+}
+
+#content #cloud .reload
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+ padding-left: 21px;
+ float: left;
+}
+
+#content #cloud .reload.loader
+{
+ padding-left: 0;
+}
+
+#content #cloud .details-button
+{
+ background-image: url(../../img/ico/ui-check-box-uncheck.png);
+ background-position: 0 50%;
+ color: #8D8D8D;
+ margin-top: 7px;
+ margin-left: 10px;
+ padding-left: 21px;
+ width: 30px;
+}
+
+#content #cloud .details-button.on
+{
+ background-image: url( ../../img/ico/ui-check-box.png );
+ color: #333;
+}
+
+#content #cloud #nodes-content .more
+{
+ font-style: italic;
+ text-underline: #0000fa;
+}
+
+/* Disk usage details d3 chart bars style */
+.chart {
+ background: #eee;
+ padding: 1px;
+}
+.chart div {
+ width:90%;
+}
+.chart div div {
+ display:inline-block;
+}
+.chart div div.rect {
+ transition: all 0.5s ease-out;
+ -moz-transition: all 0.5s ease-out;
+ -webkit-transition: all 0.5s ease-out;
+ width:0;
+ font: 10px sans-serif;
+ background-color: #4CAF50;
+ text-align: left;
+ padding: 3px;
+ margin: 2px;
+ color: #000000;
+ box-shadow: 1px 1px 1px #666;
+}
+
+#content #nodes-content .leader
+{
+ font-weight: bold;
+}
+
+#content #nodes-content .scroll-height-250
+{
+ max-height: 250px;
+ overflow-scrolling: auto;
+ overflow: auto;
+ /*overflow-y: auto;*/
+}
+
+#content #nodes-content .min-width-150
+{
+ min-width: 150px;
+}
+
+#content #cloud #nodes-content .node-cores
+{
+ min-width: 150px;
+}
+
+#content #nodes-content .core-details
+{
+ padding-left: 21px;
+}
+
+
+
+::-webkit-scrollbar {
+ -webkit-appearance: none;
+ width: 7px;
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 4px;
+ background-color: rgba(0,0,0,.5);
+ -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
+}
+#content #cloud #zk-table td,
+#content #cloud #zk-table th
+{
+ border: 0px solid #ddd;
+ border-bottom: 0.50px solid #eee;
+ padding-right: 5px;
+ padding-left: 5px;
+}
+
+#content #cloud #zk-table th
+{
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ font-weight: bolder;
+ font-stretch: extra-expanded;
+ background: #F8F8F8;
+}
+
+#content #cloud #zk-table
+{
+ border-top: 1px solid #c0c0c0;
+ margin-top: 10px;
+ border-collapse: collapse;
+
+ font-weight: bold;
+}
+
+#content #cloud #zk-table #detail-divider
+{
+ background-color: #f8f8f8;
+ height: 10px;
+}
+
+.zookeeper-status
+{
+ font-size: large;
+}
+
+.zookeeper-errors
+{
+ background-color: lightpink;
+ padding: 10px;
+ border: 1px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.zookeeper-errors li::before
+{
+ content: "- ";
+}
+
+.zkstatus-green
+{
+ color: darkgreen;
+}
+
+.zkstatus-yellow
+{
+ color: orange;
+}
+
+.zkstatus-red
+{
+ color: red;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/collections.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/collections.css
new file mode 100755
index 0000000000..e8d1207e16
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/collections.css
@@ -0,0 +1,366 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #collections
+{
+ position: relative;
+}
+
+#content #collections #ui-block
+{
+ background-color: #fff;
+ height: 200px;
+ position: absolute;
+ left: -5px;
+ top: 35px;
+ width: 500px;
+}
+
+#content #collections #frame
+{
+ float: right;
+ width: 86%;
+}
+
+#content #collections #navigation
+{
+ padding-top: 50px;
+ width: 12%;
+}
+
+#content #collections #navigation a
+{
+ padding-left: 5px;
+}
+
+#content #collections #frame .actions
+{
+ margin-bottom: 20px;
+ min-height: 30px;
+}
+
+#content #collections .actions div.action
+{
+ width: 320px;
+}
+
+#content #collections .actions div.action .cloud
+{
+}
+
+#content #collections .actions form .directory-note
+{
+ background-image: url( ../../img/ico/information-white.png );
+ background-position: 22% 1px;
+ color: #4D4D4D;
+}
+
+#content #collections .actions form .error
+{
+ background-image: url( ../../img/ico/cross-button.png );
+ background-position: 22% 1px;
+ color: #c00;
+ font-weight: bold;
+}
+
+#content #collections .actions form p
+{
+ padding-bottom: 8px;
+}
+
+#content #collections .actions form label
+{
+ float: left;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ text-align: right;
+ width: 25%;
+}
+
+#content #collections .actions form input,
+#content #collections .actions form select,
+#content #collections .actions form .chosen-container
+#content #collections .actions form .buttons,
+#content #collections .actions form .note span
+{
+ float: right;
+ width: 71%;
+}
+
+#content #collections .actions form .note span
+{
+ padding-left: 3px;
+ padding-right: 3px;
+}
+
+#content #collections .actions form .buttons
+{
+ padding-top: 10px;
+}
+
+#content #collections .actions form button.submit
+{
+ margin-right: 20px;
+}
+
+#content #collections .actions form button.submit span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #collections .actions form button.reset span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #collections .actions #add
+{
+ left: 0;
+ position: absolute;
+}
+
+#content #collections .actions #add span
+{
+ background-image: url( ../../img/ico/plus-button.png );
+}
+
+#content #collections .actions #delete
+{
+ margin-right: 20px;
+}
+
+#content #collections .actions #delete span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #collections .actions #reload span
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+}
+
+#content #collections .actions #rename span
+{
+ background-image: url( ../../img/ico/ui-text-field-select.png );
+}
+
+#content #collections .actions #create-alias span
+{
+ background-image: url( ../../img/ico/arrow-switch.png );
+}
+
+#content #collections .actions #delete-alias span
+{
+ background-image: url( ../../img/ico/cross-button.png );
+}
+
+
+#content #collections .actions div.action
+{
+ background-color: #fff;
+ border: 1px solid #f0f0f0;
+ box-shadow: 5px 5px 10px #c0c0c0;
+ -moz-box-shadow: 5px 5px 10px #c0c0c0;
+ -webkit-box-shadow: 5px 5px 10px #c0c0c0;
+ position: absolute;
+ left: 50px;
+ top: 40px;
+ padding: 10px;
+}
+
+#content #collections .actions #add-replica span
+{
+ background-image: url( ../../img/ico/plus-button.png );
+}
+
+#content #collections div.action.add-replica {
+ border: 1px solid #f0f0f0;
+ width: 400px;
+ margin-right: 0px;
+ padding: 10px;
+ float: right;
+}
+
+#content #collections div.action.add-replica p {
+ padding-bottom: 8px;
+}
+
+#content #collections div.action.add-replica .buttons {
+ float: right;
+}
+
+#content #collections div.action.add-replica .buttons .submit span {
+ background-image: url( ../../img/ico/tick.png );
+ background-position: 0% 50%;
+}
+
+#content #collections div.action.add-replica .buttons .reset span {
+ background-image: url( ../../img/ico/cross.png );
+ background-position: 0% 50%;
+}
+
+#content #collections #data #collection-data h2 { background-image: url( ../../img/ico/box.png ); }
+#content #collections #data #shard-data h2 { background-image: url( ../../img/ico/sitemap.png ); }
+#content #collections #data #shard-data .replica h2 { background-image: url( ../../img/ico/node-slave.png ); }
+
+#content #collections #data #index-data
+{
+ margin-top: 10px;
+}
+
+#content #collections #data li
+{
+ padding-bottom: 3px;
+ padding-top: 3px;
+}
+
+#content #collections #data li.odd
+{
+ background-color: #f8f8f8;
+}
+
+#content #collections #data li dt
+{
+ float: left;
+ width: 50%;
+}
+
+#content #collections #data li dd
+{
+ float: right;
+ width: 50%;
+}
+
+#content #collections #data li dd.ico
+{
+ background-image: url( ../../img/ico/slash.png );
+ height: 20px;
+}
+
+#content #collections #data li dd.ico.ico-1
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #collections #data li dd.ico span
+{
+}
+
+#content #collections #add_advanced {
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+}
+
+#content #collections #add_advanced.open {
+ background-image: url( ../../img/ico/chevron-small.png );
+}
+
+#content #collections .shard {
+ margin-left: 40px;
+}
+
+#content #collections .replica {
+ margin-left: 40px;
+}
+
+#content #collections .shard h2 span.openReplica {
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+}
+
+#content #collections .shard h2 span.openReplica .open {
+ background-image: url( ../../img/ico/chevron-small.png );
+}
+
+#content #collections .replica h2 span {
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+}
+
+#content #collections .replica h2 span.rem {
+ background-image: url( ../../img/ico/cross.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+ right:10px;
+}
+
+#content #collections .shard h2 span.rem {
+ background-image: url( ../../img/ico/cross.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+ right:10px;
+}
+
+#content #collections .replica h2 span .open {
+ background-image: url( ../../img/ico/chevron-small.png );
+}
+
+#content #collections #add-replica {
+ float: right;
+}
+
+#content #collections .add select {
+ width: 100%;
+}
+
+#content #collections .chosen-container ul {
+ width: 100%;
+ padding: 5px;
+}
+
+#content #collections .delete-replica span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+#content #collections .delete-replica button.submit span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #collections .delete-shard span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+#content #collections .delete-shard button.submit span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #collections #node-name .chosen-container
+{
+ width: 100% !important;
+}
+
+#content #collections #collection-data {
+ float: left;
+ width: 35%;
+}
+
+#content #collections #shard-data {
+ float: left;
+ width: 65%;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/common.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/common.css
new file mode 100755
index 0000000000..fecffb6d42
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/common.css
@@ -0,0 +1,771 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+*
+{
+ background-repeat: no-repeat;
+ margin: 0;
+ padding: 0;
+}
+
+body, h1, h2, h3, h4, h5, h6, a, button, input, select, option, textarea, th, td, div.ui-tooltip-content
+{
+ color: #333;
+ font: 12px/1.6em "Lucida Grande", "DejaVu Sans", "Bitstream Vera Sans", Verdana, Arial, sans-serif;
+}
+
+body
+{
+ padding: 30px;
+ text-align: center;
+}
+
+a, button
+{
+ cursor: pointer;
+}
+
+input, select, textarea
+{
+ border: 1px solid #c0c0c0;
+ padding: 2px;
+}
+
+input[readonly=readonly]
+{
+ border-color: #f0f0f0;
+}
+
+button
+{
+ background-color: #e6e6e6;
+ background-repeat: no-repeat;
+ background-image: -webkit-gradient( linear, 0 0, 0 100%, from( #ffffff ), color-stop( 25%, #ffffff ), to( #e6e6e6 ) );
+ background-image: -webkit-linear-gradient( #ffffff, #ffffff 25%, #e6e6e6 );
+ background-image: -moz-linear-gradient( top, #ffffff, #ffffff 25%, #e6e6e6 );
+ background-image: -ms-linear-gradient( #ffffff, #ffffff 25%, #e6e6e6 );
+ background-image: -o-linear-gradient( #ffffff, #ffffff 25%, #e6e6e6 );
+ background-image: linear-gradient( #ffffff, #ffffff 25%, #e6e6e6 );
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0 );
+ border: 1px solid #ccc;
+ border-bottom-color: #bbb;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.2 ), 0 1px 2px rgba( 0, 0, 0, 0.05 );
+ -moz-box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.2 ), 0 1px 2px rgba( 0, 0, 0, 0.05 );
+ box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.2 ), 0 1px 2px rgba( 0, 0, 0, 0.05 );
+ color: #333;
+ cursor: pointer;
+ display: inline-block;
+ padding: 4px 7px 5px;
+ overflow: visible;
+ text-shadow: 0 1px 1px rgba( 255, 255, 255, 0.75 );
+ -webkit-transition: 0.1s linear background-image;
+ -moz-transition: 0.1s linear background-image;
+ -ms-transition: 0.1s linear background-image;
+ -o-transition: 0.1s linear background-image;
+ transition: 0.1s linear background-image;
+}
+
+button span
+{
+ background-position: 0 50%;
+ display: block;
+ padding-left: 21px;
+}
+
+button[type=submit], button.primary
+{
+ background-color: #0064cd;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient( linear, left top, left bottom, from( #049cdb ), to( #0064cd ) );
+ background-image: -moz-linear-gradient( top, #049cdb, #0064cd );
+ background-image: -ms-linear-gradient( top, #049cdb, #0064cd );
+ background-image: -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #049cdb ), color-stop( 100%, #0064cd ) );
+ background-image: -webkit-linear-gradient( top, #049cdb, #0064cd );
+ background-image: -o-linear-gradient( top, #049cdb, #0064cd );
+ background-image: linear-gradient( top, #049cdb, #0064cd );
+ border-color: #0064cd #0064cd #003f81;
+ border-color: rgba( 0, 0, 0, 0.1 ) rgba( 0, 0, 0, 0.1 ) rgba( 0, 0, 0, 0.25 );
+ color: #ffffff;
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0 );
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+button.success
+{
+ background-color: #57a957;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient( linear, left top, left bottom, from( #62c462 ), to( #57a957 ) );
+ background-image: -moz-linear-gradient( top, #62c462, #57a957 );
+ background-image: -ms-linear-gradient( top, #62c462, #57a957 );
+ background-image: -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #62c462 ), color-stop( 100%, #57a957 ) );
+ background-image: -webkit-linear-gradient( top, #62c462, #57a957 );
+ background-image: -o-linear-gradient( top, #62c462, #57a957 );
+ background-image: linear-gradient( top, #62c462, #57a957 );
+ border-color: #57a957 #57a957 #3d773d;
+ border-color: rgba( 0, 0, 0, 0.1 ) rgba( 0, 0, 0, 0.1 ) rgba( 0, 0, 0, 0.25 );
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#62c462', endColorstr='#57a957', GradientType=0 );
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba( 0, 0, 0, 0.25 );
+}
+
+button.warn
+{
+ background-color: #c43c35;
+ background-repeat: repeat-x;
+ background-image: -khtml-gradient( linear, left top, left bottom, from( #ee5f5b ), to( #c43c35 ) );
+ background-image: -moz-linear-gradient( top, #ee5f5b, #c43c35 );
+ background-image: -ms-linear-gradient( top, #ee5f5b, #c43c35 );
+ background-image: -webkit-gradient( linear, left top, left bottom, color-stop( 0%, #ee5f5b ), color-stop( 100%, #c43c35 ) );
+ background-image: -webkit-linear-gradient( top, #ee5f5b, #c43c35 );
+ background-image: -o-linear-gradient( top, #ee5f5b, #c43c35 );
+ background-image: linear-gradient( top, #ee5f5b, #c43c35 );
+ border-color: #c43c35 #c43c35 #882a25;
+ border-color: rgba( 0, 0, 0, 0.1 ) rgba( 0, 0, 0, 0.1 ) rgba( 0, 0, 0, 0.25 );
+ color: #ffffff;
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0 );
+ text-shadow: 0 -1px 0 rgba( 0, 0, 0, 0.25 );
+}
+
+a
+{
+ text-decoration: none;
+}
+
+pre
+{
+ color: #333;
+ text-align: left;
+}
+
+abbr
+{
+ cursor: help;
+}
+
+ul
+{
+ list-style: none;
+}
+
+.clearfix:after { clear: both; content: "."; display: block; font-size: 0; height: 0; visibility: hidden; }
+.clearfix { display: block; }
+
+.loader
+{
+ background-image: url( ../../img/loader.gif ) !important;
+}
+
+.loader-light
+{
+ background-image: url( ../../img/loader-light.gif ) !important;
+}
+
+.universal-loader {
+ position: absolute;
+ left: -16px;
+ top: 0px;
+ width: 16px;
+ height: 16px;
+}
+
+#wrapper
+{
+ position: relative;
+ margin: 0 auto;
+ margin-bottom: 30px;
+ text-align: left;
+}
+
+#header
+{
+ padding-bottom: 10px;
+ position: fixed;
+ z-index: 42;
+}
+
+.scroll #header
+{
+ position: absolute;
+}
+
+#header #solr
+{
+ background-image: url( ../../img/solr.svg );
+ background-size: 128px;
+ display: block;
+ height: 78px;
+ width: 150px;
+}
+
+#header #solr span
+{
+ display: none;
+}
+
+#main
+{
+ min-width: 750px;
+ position: relative;
+}
+
+#main.error
+{
+ border: 0;
+ min-height: 0;
+ padding-top: 20px;
+}
+
+#main.error .message
+{
+ background-color: #f00;
+ background-image: url( ../../img/ico/construction.png );
+ background-position: 10px 50%;
+ color: #fff;
+ font-weight: bold;
+ margin-left: 150px;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+}
+
+#main.error .code
+{
+ border: 1px solid #c0c0c0;
+ padding: 5px;
+}
+
+#meta
+{
+ position: absolute;
+ bottom: -26px;
+ right: 0;
+}
+
+#meta li
+{
+ float: left;
+}
+
+#meta li a
+{
+ background-position: 10px 50%;
+ display: block;
+ height: 25px;
+ line-height: 25px;
+ padding-left: 31px;
+ padding-right: 10px;
+}
+
+#meta li a:hover
+{
+ background-color: #f0f0f0;
+}
+
+#meta .documentation a { background-image: url( ../../img/ico/document-text.png ); }
+#meta .issues a { background-image: url( ../../img/ico/bug.png ); }
+#meta .irc a { background-image: url( ../../img/ico/users.png ); }
+#meta .mailinglist a { background-image: url( ../../img/ico/mail.png ); }
+#meta .wiki-query-syntax a { background-image: url( ../../img/ico/script-code.png ); }
+
+#environment
+{
+ background-image: url( ../../img/ico/box.png );
+ background-position: 5px 50%;
+ font-weight: bold;
+ padding: 5px 10px;
+ padding-left: 26px;
+}
+
+.has-environment #environment
+{
+ display: block;
+}
+
+#environment.prod
+{
+ background-color: #c37f7f;
+ color: #fff;
+}
+
+#environment.stage
+{
+ background-color: orange;
+ color: #fff;
+}
+
+#environment.test
+{
+ background-color: #f5f5b2;
+}
+
+#environment.dev
+{
+ background-color: #cce7cc;
+}
+
+.header-message
+{
+ border: 1px solid #f00;
+ margin-left: 150px;
+ margin-bottom: 20px;
+}
+
+.header-message h2,
+.header-message ul,
+.header-message p
+{
+ padding: 10px;
+}
+
+.header-message h2
+{
+ background-color: #f00;
+ color: #fff;
+ font-weight: bold;
+}
+
+.header-message p
+{
+ color: #4D4D4D;
+ padding-top: 0;
+}
+
+#loading
+#http-exception
+{
+ display: none;
+}
+
+.exception
+{
+ background-color: #f00;
+ background-image: url( ../../img/ico/construction.png );
+ background-position: 10px 50%;
+ color: #fff;
+ font-weight: bold;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+}
+
+#content-wrapper
+{
+ margin-left: 150px;
+ border: 1px solid #c0c0c0;
+ min-height: 500px;
+}
+
+#content
+{
+ padding: 10px;
+}
+
+#content > .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content iframe
+{
+ border: 0;
+ display: block;
+ min-height: 400px;
+ width: 100%;
+}
+
+#content .block
+{
+ margin-bottom: 10px;
+}
+
+#content .block h2
+{
+ background-color: #fafafa;
+ background-position: 5px 50%;
+ border-bottom: 1px solid #f0f0f0;
+ font-weight: bold;
+ padding: 5px;
+ padding-left: 26px;
+}
+
+#content .block.disabled,
+#content .block.disabled h2
+{
+ color: #c0c0c0;
+}
+
+#content .block .message,
+#content .block .content
+{
+ padding: 5px;
+}
+
+/* syntax */
+
+pre.syntax
+{
+ overflow: auto;
+}
+
+pre.syntax code
+{
+ display: block;
+ color: #000;
+}
+
+pre.syntax .comment,
+pre.syntax .template_comment,
+pre.syntax .diff .header,
+pre.syntax .javadoc
+{
+ color: #998;
+ font-style: italic;
+}
+
+pre.syntax .keyword,
+pre.syntax .css .rule .keyword,
+pre.syntax .winutils,
+pre.syntax .javascript .title,
+pre.syntax .lisp .title,
+pre.syntax .subst
+{
+ color: #000;
+ font-weight: bold;
+}
+
+pre.syntax .number,
+pre.syntax .hexcolor
+{
+ color: #40a070;
+}
+
+pre.syntax.language-json .number
+{
+ color: blue;
+}
+
+pre.syntax.language-json .literal
+{
+ color: firebrick;
+}
+
+pre.syntax .string,
+pre.syntax .tag .value,
+pre.syntax .phpdoc,
+pre.syntax .tex .formula
+{
+ color: #d14;
+}
+
+pre.syntax.language-json .string
+{
+ color: green;
+}
+
+pre.syntax .title,
+pre.syntax .id
+{
+ color: #900;
+ font-weight: bold;
+}
+
+pre.syntax .javascript .title,
+pre.syntax .lisp .title,
+pre.syntax .subst
+{
+ font-weight: normal;
+}
+
+pre.syntax .class .title,
+pre.syntax .tex .command
+{
+ color: #458;
+ font-weight: bold;
+}
+
+pre.syntax .tag,
+pre.syntax .css .keyword,
+pre.syntax .html .keyword,
+pre.syntax .tag .title,
+pre.syntax .django .tag .keyword
+{
+ color: #000080;
+ font-weight: normal;
+}
+
+pre.syntax .attribute,
+pre.syntax .variable,
+pre.syntax .instancevar,
+pre.syntax .lisp .body
+{
+ color: #008080;
+}
+
+pre.syntax.language-json .attribute
+{
+ color: black;
+ font-weight: bold;
+}
+
+pre.syntax .regexp
+{
+ color: #009926;
+}
+
+pre.syntax .class
+{
+ color: #458;
+ font-weight: bold;
+}
+
+pre.syntax .symbol,
+pre.syntax .ruby .symbol .string,
+pre.syntax .ruby .symbol .keyword,
+pre.syntax .ruby .symbol .keymethods,
+pre.syntax .lisp .keyword,
+pre.syntax .tex .special
+{
+ color: #990073;
+}
+
+pre.syntax .builtin,
+pre.syntax .built_in,
+pre.syntax .lisp .title
+{
+ color: #0086b3;
+}
+
+pre.syntax .preprocessor,
+pre.syntax .pi,
+pre.syntax .doctype,
+pre.syntax .shebang,
+pre.syntax .cdata
+{
+ color: #999;
+ font-weight: bold;
+}
+
+pre.syntax .deletion
+{
+ background: #fdd;
+}
+
+pre.syntax .addition
+{
+ background: #dfd;
+}
+
+pre.syntax .diff .change
+{
+ background: #0086b3;
+}
+
+pre.syntax .chunk
+{
+ color: #aaa;
+}
+
+pre.syntax .tex .formula
+{
+ opacity: 0.5;
+}
+
+#content .tree li,
+#content .tree ins
+{
+ background-color: transparent;
+ background-image: url( ../../img/tree.png );
+ background-repeat: no-repeat;
+}
+
+#content .tree li
+{
+ background-position: -54px 0;
+ background-repeat: repeat-y;
+ line-height: 22px;
+}
+
+#content .tree li.jstree-last
+{
+ background:transparent;
+}
+
+#content .tree .jstree-open > ins
+{
+ background-position: -36px 0;
+}
+
+#content .tree .jstree-closed > ins
+{
+ background-position: -18px 0;
+}
+
+#content .tree .jstree-leaf > ins
+{
+ background-position: 0 0;
+}
+
+#content .tree .jstree-hovered
+{
+ background:#e7f4f9; border:1px solid #d8f0fa; padding:0 2px 0 1px;
+}
+
+#content .tree .jstree-clicked
+{
+ background:#beebff; border:1px solid #99defd; padding:0 2px 0 1px;
+}
+
+#content .tree a.active
+{
+ background-color: #f0f0f0;
+ color: #00f;
+}
+
+#content .tree a .jstree-icon
+{
+ background-image: url( ../../img/ico/folder.png );
+}
+
+#content .tree .jstree-leaf a .jstree-icon
+{
+ background-image: url( ../../img/ico/document-text.png );
+}
+
+#content .tree .jstree-search
+{
+ font-style:italic;
+}
+
+#content .tree a.jstree-search
+{
+ color:aqua;
+}
+
+#connection-box
+{
+ display: none;
+}
+
+#connection-status-modal
+{
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: #e6e6e6;
+ opacity: 0.5;
+ z-index: 100;
+}
+
+#connection-status-recovered
+{
+ z-index:102;
+}
+
+.connection-status
+{
+ position: absolute;
+ left: 200px;
+ right: 200px;
+ top: 40%;
+ height: 75px;
+ border: 1px solid #f00;
+ padding: 30px;
+ background-color: #fff;
+ opacity: 1;
+ z-index: 101;
+}
+
+.connection-status p
+{
+ background-image: url( ../../img/ico/network-status-busy.png );
+ background-position: 0 50%;
+ color: #800;
+ padding-left: 26px;
+}
+
+#connection-status-recovered p
+{
+ color: #080;
+ background-image: url( ../../img/ico/network-status.png );
+}
+
+#content .address-bar
+{
+ margin-bottom: 10px;
+ background-image: url( ../../img/ico/ui-address-bar.png );
+ background-position: 5px 50%;
+ border: 1px solid #f0f0f0;
+ box-shadow: 1px 1px 0 #f0f0f0;
+ -moz-box-shadow: 1px 1px 0 #f0f0f0;
+ -webkit-box-shadow: 1px 1px 0 #f0f0f0;
+ color: #4D4D4D;
+ display: block;
+ overflow: hidden;
+ padding: 5px;
+ padding-left: 26px;
+ white-space: nowrap;
+}
+
+#content .address-bar:focus,
+#content .address-bar:hover
+{
+ border-color: #c0c0c0;
+ box-shadow: 1px 1px 0 #d8d8d8;
+ -moz-box-shadow: 1px 1px 0 #d8d8d8;
+ -webkit-box-shadow: 1px 1px 0 #d8d8d8;
+ color: #333;
+}
+
+.exception .show-exception {
+ margin-top: 4px;
+ display: block;
+ position: absolute;
+ right: 10px;
+ top: 7px;
+ color: #fff;
+}
+
+#exception .show-exception a:hover {
+ color: #333;
+}
+
+.other-ui-link {
+ margin: 0px;
+ position: absolute;
+ right: 0px;
+ top: -20px;
+}
+
+.other-ui-link span,
+.new-ui-warning span.help {
+ background-image: url( ../../img/ico/information-white.png );
+ right: 0px;
+ padding-left: 16px;
+}
+
+.other-ui-link a.ul {
+ text-decoration: underline;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/cores.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/cores.css
new file mode 100755
index 0000000000..0428c664b3
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/cores.css
@@ -0,0 +1,225 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #cores
+{
+ position: relative;
+}
+
+#content #cores #ui-block
+{
+ background-color: #fff;
+ height: 200px;
+ position: absolute;
+ left: -5px;
+ top: 35px;
+ width: 500px;
+}
+
+#content #cores #frame
+{
+ float: right;
+ width: 86%;
+}
+
+#content #cores #navigation
+{
+ padding-top: 50px;
+ width: 12%;
+}
+
+#content #cores #navigation a
+{
+ padding-left: 5px;
+}
+
+#content #cores #frame .actions
+{
+ margin-bottom: 20px;
+ min-height: 30px;
+}
+
+#content #cores .actions div.action
+{
+ width: 320px;
+}
+
+#content #cores .actions div.action .cloud
+{
+}
+
+#content #cores .actions form .directory-note
+{
+ background-image: url( ../../img/ico/information-white.png );
+ background-position: 22% 1px;
+ color: #4D4D4D;
+}
+
+#content #cores .actions form .error
+{
+ background-image: url( ../../img/ico/cross-button.png );
+ background-position: 22% 1px;
+ color: #c00;
+ font-weight: bold;
+}
+
+#content #cores .actions form p
+{
+ padding-bottom: 8px;
+}
+
+#content #cores .actions form label
+{
+ float: left;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ text-align: right;
+ width: 25%;
+}
+
+#content #cores .actions form input,
+#content #cores .actions form select,
+#content #cores .actions form .buttons,
+#content #cores .actions form .note span
+{
+ float: right;
+ width: 71%;
+}
+
+#content #cores .actions form .note span
+{
+ padding-left: 3px;
+ padding-right: 3px;
+}
+
+#content #cores .actions form .buttons
+{
+ padding-top: 10px;
+}
+
+#content #cores .actions form button.submit
+{
+ margin-right: 20px;
+}
+
+#content #cores .actions form button.submit span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #cores .actions form button.reset span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #cores .actions #add
+{
+ left: 0;
+ position: absolute;
+}
+
+#content #cores .actions #add span
+{
+ background-image: url( ../../img/ico/plus-button.png );
+}
+
+#content #cores .actions #unload
+{
+ margin-right: 20px;
+}
+
+#content #cores .actions #unload span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #cores .actions #reload span
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+}
+
+#content #cores .actions #rename span
+{
+ background-image: url( ../../img/ico/ui-text-field-select.png );
+}
+
+#content #cores .actions #swap span
+{
+ background-image: url( ../../img/ico/arrow-switch.png );
+}
+
+
+#content #cores .actions div.action
+{
+ background-color: #fff;
+ border: 1px solid #f0f0f0;
+ box-shadow: 5px 5px 10px #c0c0c0;
+ -moz-box-shadow: 5px 5px 10px #c0c0c0;
+ -webkit-box-shadow: 5px 5px 10px #c0c0c0;
+ position: absolute;
+ left: -50px;
+ top: 40px;
+ padding: 10px;
+}
+
+#content #cores #data #core-data h2 { background-image: url( ../../img/ico/box.png ); }
+#content #cores #data #index-data h2 { background-image: url( ../../img/ico/chart.png ); }
+
+#content #cores #data #index-data
+{
+ margin-top: 10px;
+}
+
+#content #cores #data li
+{
+ padding-bottom: 3px;
+ padding-top: 3px;
+}
+
+#content #cores #data li.odd
+{
+ background-color: #f8f8f8;
+}
+
+#content #cores #data li dt
+{
+ float: left;
+ width: 17%;
+}
+
+#content #cores #data li dd
+{
+ float: right;
+ width: 82%;
+}
+
+#content #cores #data li dd.ico
+{
+ background-image: url( ../../img/ico/slash.png );
+ height: 20px;
+}
+
+#content #cores #data li dd.ico.ico-1
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #cores #data li dd.ico span
+{
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dashboard.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dashboard.css
new file mode 100755
index 0000000000..734d62a9de
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dashboard.css
@@ -0,0 +1,179 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #dashboard .block
+{
+ background-image: none;
+ width: 49%;
+}
+
+#content #dashboard .fieldlist
+{
+ float: left;
+}
+
+#content #dashboard .fieldlist dt,
+#content #dashboard .fieldlist dd
+{
+ display: block;
+ float: left;
+}
+
+#content #dashboard .fieldlist dt
+{
+ clear: left;
+ margin-right: 2%;
+ text-align: right;
+ width: 23%;
+}
+
+#content #dashboard .fieldlist dd
+{
+ width: 74%;
+}
+
+#content #dashboard .fieldlist .index_optimized
+{
+ margin-top: 10px;
+}
+
+#content #dashboard .fieldlist .ico
+{
+ background-image: url( ../../img/ico/slash.png );
+ height: 20px;
+}
+
+#content #dashboard .fieldlist .ico.ico-1
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #dashboard .fieldlist .ico span
+{
+ display: none;
+}
+
+#content #dashboard #statistics .index_optimized.value a
+{
+ display: none;
+}
+
+#content #dashboard #statistics .index_optimized.value.ico-0 a
+{
+ background-color: #f0f0f0;
+ background-image: url( ../../img/ico/hammer-screwdriver.png );
+ background-position: 5px 50%;
+ border: 1px solid #c0c0c0;
+ display: block;
+ float: left;
+ margin-left: 50px;
+ padding: 1px 5px;
+ padding-left: 26px;
+}
+
+#content #dashboard #statistics .index_has-deletions
+{
+ display: none;
+}
+
+#content #dashboard #statistics .index_has-deletions.value.ico-0
+{
+ background-image: url( ../../img/ico/tick-red.png );
+}
+
+#content #dashboard #replication
+{
+ float: left;
+}
+
+#content #dashboard #replication .is-replicating
+{
+ background-position: 99% 50%;
+ display: block;
+}
+
+#content #dashboard #replication #details table thead td span
+{
+ display: none;
+}
+
+#content #dashboard #instance
+{
+ float: right;
+}
+
+#content #dashboard #instance .dir_impl
+{
+ margin-top: 10px;
+}
+
+#content #dashboard #healthcheck
+{
+ float: right;
+}
+
+#content #dashboard #healthcheck .ico
+{
+ background-image: url( ../../img/ico/slash.png );
+ height: 20px;
+ padding-left: 20px;
+ width: 60%;
+}
+
+#content #dashboard #healthcheck .ico.ico-1
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #dashboard #system h2 { background-image: url( ../../img/ico/server.png ); }
+#content #dashboard #statistics h2 { background-image: url( ../../img/ico/chart.png ); }
+#content #dashboard #replication h2 { background-image: url( ../../img/ico/node.png ); }
+#content #dashboard #replication.master h2 { background-image: url( ../../img/ico/node-master.png ); }
+#content #dashboard #replication.slave h2 { background-image: url( ../../img/ico/node-slave.png ); }
+#content #dashboard #instance h2 { background-image: url( ../../img/ico/server.png ); }
+#content #dashboard #collection h2 { background-image: url( ../../img/ico/book-open-text.png ); }
+#content #dashboard #shards h2 { background-image: url( ../../img/ico/documents-stack.png ); }
+
+#content #dashboard #shards { margin-left: 20px;}
+
+#dashboard #shards .shard h3.shard-title {
+ display: block;
+ background-color: #c8c8c8;
+ font-weight: bold;
+ padding: 3px;
+ padding-left: 30px;
+ margin-left: 20px;
+ margin-top: 20px;
+ background-image: url( ../../img/ico/document-text.png );
+ background-position-x: 10px;
+ background-position-y: 3px;
+}
+
+#dashboard #shards .shard .shard-detail {
+ margin-bottom: 25px;
+ margin-top: 7px;
+}
+
+#dashboard #shards .shard .replica {
+ background-color: #e4e4e4;
+}
+
+#dashboard #shards .shard .replica.odd {
+ background-color: #fff;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dataimport.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dataimport.css
new file mode 100755
index 0000000000..6afb096ca6
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/dataimport.css
@@ -0,0 +1,370 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #dataimport
+{
+ background-image: url( ../../img/div.gif );
+ background-position: 21% 0;
+ background-repeat: repeat-y;
+}
+
+#content #dataimport #frame
+{
+ float: right;
+ width: 78%;
+}
+
+#content #dataimport #form
+{
+ float: left;
+ width: 20%;
+}
+
+#content #dataimport #form #navigation
+{
+ border-right: 0;
+}
+
+#content #dataimport #form #navigation a
+{
+ background-image: url( ../../img/ico/status-offline.png );
+}
+
+#content #dataimport #form #navigation .current a
+{
+ background-image: url( ../../img/ico/status.png );
+}
+
+#content #dataimport #form form
+{
+ border-top: 1px solid #f0f0f0;
+ margin-top: 10px;
+ padding-top: 5px;
+}
+
+#content #dataimport #form label
+{
+ cursor: pointer;
+ display: block;
+ margin-top: 5px;
+}
+
+#content #dataimport #form input,
+#content #dataimport #form select,
+#content #dataimport #form textarea
+{
+ margin-bottom: 2px;
+ width: 100%;
+}
+
+#content #dataimport #form input
+{
+ width: 98%;
+}
+
+#content #dataimport #form button
+{
+ margin-top: 10px;
+}
+
+#content #dataimport #form .execute span
+{
+ background-image: url( ../../img/ico/document-import.png );
+}
+
+#content #dataimport #form .refresh-status span
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+}
+
+#content #dataimport #form .refresh-status span.success
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #dataimport #form #start
+{
+ float: left;
+ width: 47%;
+}
+
+#content #dataimport #form #rows
+{
+ float: right;
+ width: 47%;
+}
+
+#content #dataimport #form .checkbox input
+{
+ margin-bottom: 0;
+ width: auto;
+}
+
+#content #dataimport #form #auto-refresh-status
+{
+ margin-top: 20px;
+}
+
+#content #dataimport #form #auto-refresh-status a
+{
+ background-image: url( ../../img/ico/ui-check-box-uncheck.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ display: block;
+ padding-left: 21px;
+}
+
+#content #dataimport #form #auto-refresh-status a.on,
+#content #dataimport #form #auto-refresh-status a:hover
+{
+ color: #333;
+}
+
+#content #dataimport #form #auto-refresh-status a.on
+{
+ background-image: url( ../../img/ico/ui-check-box.png );
+}
+
+#content #dataimport #current_state
+{
+ padding: 10px;
+ margin-bottom: 20px;
+}
+
+#content #dataimport #current_state .last_update,
+#content #dataimport #current_state .info
+{
+ display: block;
+ padding-left: 21px;
+}
+
+#content #dataimport #current_state .last_update
+{
+ color: #4D4D4D;
+ font-size: 11px;
+}
+
+#content #dataimport #current_state .info
+{
+ background-position: 0 1px;
+ position: relative;
+}
+
+#content #dataimport #current_state .info .details span
+{
+ color: #c0c0c0;
+}
+
+#content #dataimport #current_state .info .abort-import
+{
+ position: absolute;
+ right: 0px;
+ top: 0px;
+}
+
+#content #dataimport #current_state .info .abort-import span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #dataimport #current_state .info .abort-import.success span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #dataimport #current_state.indexing
+{
+ background-color: #f9f9f9;
+}
+
+#content #dataimport #current_state.indexing .info
+{
+ background-image: url( ../../img/ico/hourglass.png );
+}
+
+#content #dataimport #current_state.indexing .info .abort-import
+{
+ display: block;
+}
+
+#content #dataimport #current_state.success
+{
+ background-color: #e6f3e6;
+}
+
+#content #dataimport #current_state.success .info
+{
+ background-image: url( ../../img/ico/tick-circle.png );
+}
+
+#content #dataimport #current_state.success .info strong
+{
+ color: #080;
+}
+
+#content #dataimport #current_state.aborted
+{
+ background-color: #f3e6e6;
+}
+
+#content #dataimport #current_state.aborted .info
+{
+ background-image: url( ../../img/ico/slash.png );
+}
+
+#content #dataimport #current_state.aborted .info strong
+{
+ color: #800;
+}
+
+#content #dataimport #current_state.failure
+{
+ background-color: #f3e6e6;
+}
+
+#content #dataimport #current_state.failure .info
+{
+ background-image: url( ../../img/ico/cross-button.png );
+}
+
+#content #dataimport #current_state.failure .info strong
+{
+ color: #800;
+}
+
+#content #dataimport #current_state.idle
+{
+ background-color: #e6e6ff;
+}
+
+#content #dataimport #current_state.idle .info
+{
+ background-image: url( ../../img/ico/information.png );
+}
+
+#content #dataimport #error
+{
+ background-color: #f00;
+ background-image: url( ../../img/ico/construction.png );
+ background-position: 10px 50%;
+ color: #fff;
+ font-weight: bold;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+}
+
+#content #dataimport .block h2
+{
+ border-color: #c0c0c0;
+ padding-left: 5px;
+ position: relative;
+}
+
+#content #dataimport .block.hidden h2
+{
+ border-color: #fafafa;
+}
+
+#content #dataimport .block h2 a.toggle
+{
+ background-image: url( ../../img/ico/toggle-small.png );
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #dataimport .block.hidden h2 a.toggle
+{
+ background-image: url( ../../img/ico/toggle-small-expand.png );
+}
+
+#content #dataimport #config h2 a.r
+{
+ background-position: 3px 50%;
+ display: block;
+ float: right;
+ margin-left: 10px;
+ padding-left: 24px;
+ padding-right: 3px;
+}
+
+#content #dataimport #config h2 a.reload_config
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+}
+
+#content #dataimport #config h2 a.reload_config.success
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #dataimport #config h2 a.reload_config.error
+{
+ background-image: url( ../../img/ico/slash.png );
+}
+
+#content #dataimport #config h2 a.debug_mode
+{
+ background-image: url( ../../img/ico/hammer.png );
+ color: #4D4D4D;
+}
+
+#content #dataimport #config.debug_mode h2 a.debug_mode
+{
+ background-color: #ff0;
+ background-image: url( ../../img/ico/hammer-screwdriver.png );
+ color: #333;
+}
+
+#content #dataimport #config .content
+{
+ padding: 5px 2px;
+}
+
+#content #dataimport #dataimport_config .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #dataimport #dataimport_config .formatted
+{
+ border: 1px solid #fff;
+ display: block;
+ padding: 2px;
+}
+
+#content #dataimport .debug_mode #dataimport_config .editable
+{
+ display: block;
+}
+
+#content #dataimport #dataimport_config .editable textarea
+{
+ font-family: monospace;
+ height: 120px;
+ min-height: 60px;
+ width: 100%;
+}
+
+#content #dataimport #debug_response em
+{
+ color: #4D4D4D;
+ font-style: normal;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/documents.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/documents.css
new file mode 100755
index 0000000000..2f0ba12ed7
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/documents.css
@@ -0,0 +1,179 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #documents
+{
+ background-image: url( ../../img/div.gif );
+ background-position: 45% 0;
+ background-repeat: repeat-y;
+}
+
+#content #documents #form
+{
+ float: left;
+ /*width: 21%;*/
+}
+
+#content #documents #form label
+{
+ cursor: pointer;
+ display: block;
+ margin-top: 5px;
+}
+
+#content #documents #form input,
+#content #documents #form select,
+#content #documents #form textarea
+{
+ margin-bottom: 2px;
+ /*width: 100%;*/
+}
+
+#content #documents #form input,
+#content #documents #form textarea
+{
+ margin-bottom: 2px;
+ /*width: 98%;*/
+}
+
+#content #documents #form #start
+{
+ float: left;
+ /*width: 45%;*/
+}
+
+#content #documents #form #rows
+{
+ float: right;
+ /* width: 45%;*/
+}
+
+#content #documents #form .checkbox input
+{
+ margin-bottom: 0;
+ width: auto;
+}
+
+#content #documents #form fieldset,
+#content #documents #form .optional.expanded
+{
+ border: 1px solid #fff;
+ border-top: 1px solid #c0c0c0;
+ margin-bottom: 5px;
+}
+
+#content #documents #form fieldset.common
+{
+ margin-top: 10px;
+}
+
+#content #documents #form fieldset legend,
+#content #documents #form .optional.expanded legend
+{
+ display: block;
+ margin-left: 10px;
+ padding: 0px 5px;
+}
+
+#content #documents #form fieldset legend label
+{
+ margin-top: 0;
+}
+
+#content #documents #form fieldset .fieldset
+{
+ border-bottom: 1px solid #f0f0f0;
+ margin-bottom: 5px;
+ padding-bottom: 10px;
+}
+
+#content #documents #form .optional
+{
+ border: 0;
+}
+
+#content #documents #form .optional legend
+{
+ margin-left: 0;
+ padding-left: 0;
+}
+
+#content #documents #form .optional.expanded .fieldset
+{
+ display: block;
+}
+
+#content #documents #result
+{
+ float: right;
+ width: 54%;
+}
+
+#content #documents #result #url
+{
+ margin-bottom: 10px;
+ background-image: url( ../../img/ico/ui-address-bar.png );
+ background-position: 5px 50%;
+ border: 1px solid #f0f0f0;
+ box-shadow: 1px 1px 0 #f0f0f0;
+ -moz-box-shadow: 1px 1px 0 #f0f0f0;
+ -webkit-box-shadow: 1px 1px 0 #f0f0f0;
+ color: #c0c0c0;
+ display: block;
+ overflow: hidden;
+ padding: 5px;
+ padding-left: 26px;
+ white-space: nowrap;
+}
+
+#content #documents #result #url:focus,
+#content #documents #result #url:hover
+{
+ border-color: #c0c0c0;
+ box-shadow: 1px 1px 0 #d8d8d8;
+ -moz-box-shadow: 1px 1px 0 #d8d8d8;
+ -webkit-box-shadow: 1px 1px 0 #d8d8d8;
+ color: #333;
+}
+
+#content #documents #result #response
+{
+}
+
+#content #documents #result #response pre
+{
+ padding-left: 20px;
+}
+
+.description{
+ font-weight: bold;
+}
+
+#document-type{
+ padding-bottom: 5px;
+}
+
+#wizard-fields div{
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+#wiz-field-data, #wiz-field-data span{
+ vertical-align: top;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/files.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/files.css
new file mode 100755
index 0000000000..46b3e8c301
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/files.css
@@ -0,0 +1,53 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #files #tree-holder
+{
+ float: left;
+ width: 20%;
+}
+
+#content #files #tree-holder li
+{
+ overflow: hidden;
+}
+
+#content #files form .buttons button
+{
+ float: right;
+}
+
+#content #files #file-content
+{
+ float: right;
+ position: relative;
+ width: 78%;
+ min-height: 100px
+}
+
+#content #files .show #file-content
+{
+ display: block;
+}
+
+#content #files #file-content .response
+{
+ border: 1px solid transparent;
+ padding: 2px;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/index.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/index.css
new file mode 100755
index 0000000000..c53e3230a7
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/index.css
@@ -0,0 +1,216 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #index .bar-desc
+{
+ color: #4D4D4D;
+ font-weight: normal;
+ margin-left: 10px;
+ white-space: pre;
+}
+
+#content #index .bar-holder
+{
+ box-shadow: 5px 5px 10px #c0c0c0;
+ -moz-box-shadow: 5px 5px 10px #c0c0c0;
+ -webkit-box-shadow: 5px 5px 10px #c0c0c0;
+ height: 35px;
+}
+
+#content #index .bar-holder .bar
+{
+ height: 100%;
+ position: relative;
+}
+
+#content #index .bar-holder div .val
+{
+ border-right: 1px solid #f00;
+ display: block;
+ padding-right: 5px;
+ position: absolute;
+ right: 0;
+ top: 35px;
+ white-space: nowrap;
+}
+
+#content #index .bar-holder .bar-max.bar
+{
+ background-color: #f0f0f0;
+}
+
+#content #index .bar-holder .bar-max.val
+{
+ border-color: #f0f0f0;
+ color: #8D8D8D;
+}
+
+#content #index .bar-holder .bar-total.bar
+{
+ background-color: #c0c0c0;
+}
+
+#content #index .bar-holder .bar-total.val
+{
+ border-color: #c0c0c0;
+ color: #4D4D4D;
+}
+
+#content #index .bar-holder .bar-used.bar
+{
+ background-color: #969696;
+}
+
+#content #index .bar-holder .bar-used.val
+{
+ border-color: #969696;
+ color: #969696;
+}
+
+#content #index .bar-holder.bar-lvl-2 .bar-max.val { padding-top: 25px; }
+#content #index .bar-holder.bar-lvl-2 .bar-total.val { padding-top: 5px; }
+#content #index .bar-holder.bar-lvl-2 { margin-bottom: 45px; }
+
+#content #index .bar-holder.bar-lvl-3 .bar-max.val { padding-top: 45px; }
+#content #index .bar-holder.bar-lvl-3 .bar-total.val { padding-top: 25px; }
+#content #index .bar-holder.bar-lvl-3 .bar-used.val { padding-top: 5px; }
+#content #index .bar-holder.bar-lvl-3 { margin-bottom: 65px; }
+
+#content #index .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #index .index-left
+{
+ float: left;
+ width: 55%;
+}
+
+#content #index .index-right
+{
+ float: right;
+ width: 40%;
+}
+
+#content #index .data
+{
+ padding-bottom: 12px;
+ overflow: hidden;
+}
+
+#content #index .data:hover
+{
+ overflow-x: auto;
+}
+
+#content #index .data li
+{
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+#content #index .data li dt
+{
+ float: left;
+ white-space: nowrap;
+ width: 20%;
+}
+
+#content #index .data li dd
+{
+ float: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ width: 80%
+}
+
+#content #index .data li dd.odd
+{
+ background-color: #f0f0f0;
+}
+
+#content #index .data dt span
+{
+ background-position: 1px 50%;
+ display: block;
+ padding-left: 22px;
+}
+
+#content #index #instance h2 { background-image: url( ../../img/ico/server.png ); }
+#content #index #instance .start_time dt span { background-image: url( ../../img/ico/clock-select.png ); }
+
+#content #index #versions h2 { background-image: url( ../../img/ico/property.png ); }
+#content #index #versions .solr span { background-image: url( ../../img/solr-ico.png ); }
+#content #index #versions .lucene span { background-image: url( ../../img/lucene-ico.png ); }
+
+#content #index #jvm h2 { background-image: url( ../../img/ico/jar.png ); }
+#content #index #jvm .jvm_version dt span { background-image: url( ../../img/ico/jar.png ); }
+#content #index #jvm .processors dt span { background-image: url( ../../img/ico/processor.png ); }
+#content #index #jvm .command_line_args dt span { background-image: url( ../../img/ico/terminal.png ); }
+
+#content #index #system h2 { background-image: url( ../../img/ico/system-monitor.png ); }
+
+#content #index #system
+{
+ position: relative;
+}
+
+#content #index #system .reload
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+ background-position: 50% 50%;
+ display: block;
+ height: 30px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 30px;
+}
+
+#content #index #system .reload.loader
+{
+ padding-left: 0;
+}
+
+#content #index #system .reload span
+{
+ display: none;
+}
+
+#content #index #system .content p
+{
+ margin-top: 10px;
+ margin-bottom: 5px;
+}
+
+#content #index #system .content .no-info
+{
+ color: #4D4D4D;
+ display: none;
+ font-style: italic;
+}
+
+#content #index #jvm-memory h2 { background-image: url( ../../img/ico/memory.png ); }
+
+#content #index #jvm-memory-bar
+{
+ margin-top: 20px;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/java-properties.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/java-properties.css
new file mode 100755
index 0000000000..d23fadfa44
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/java-properties.css
@@ -0,0 +1,47 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #java-properties .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #java-properties li
+{
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+#content #java-properties li.odd
+{
+ background-color: #f8f8f8;
+}
+
+#content #java-properties li dt
+{
+ float: left;
+ width: 29%;
+}
+
+#content #java-properties li dd
+{
+ float: right;
+ width: 70%
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jquery-ui.min.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jquery-ui.min.css
new file mode 100755
index 0000000000..b7dce77356
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jquery-ui.min.css
@@ -0,0 +1,28 @@
+/*! jQuery UI - v1.12.1 - 2017-10-31
+* http://jqueryui.com
+
+Available for use under the MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+* Includes: core.css, tooltip.css, theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=base&cornerRadiusShadow=8px&offsetLeftShadow=0px&offsetTopShadow=0px&thicknessShadow=5px&opacityShadow=30&bgImgOpacityShadow=0&bgTextureShadow=flat&bgColorShadow=666666&opacityOverlay=30&bgImgOpacityOverlay=0&bgTextureOverlay=flat&bgColorOverlay=aaaaaa&iconColorError=cc0000&fcError=5f3f3f&borderColorError=f1a899&bgTextureError=flat&bgColorError=fddfdf&iconColorHighlight=777620&fcHighlight=777620&borderColorHighlight=dad55e&bgTextureHighlight=flat&bgColorHighlight=fffa90&iconColorActive=ffffff&fcActive=ffffff&borderColorActive=003eff&bgTextureActive=flat&bgColorActive=007fff&iconColorHover=555555&fcHover=2b2b2b&borderColorHover=cccccc&bgTextureHover=flat&bgColorHover=ededed&iconColorDefault=777777&fcDefault=454545&borderColorDefault=c5c5c5&bgTextureDefault=flat&bgColorDefault=f6f6f6&iconColorContent=444444&fcContent=333333&borderColorContent=dddddd&bgTextureContent=flat&bgColorContent=ffffff&iconColorHeader=444444&fcHeader=333333&borderColorHeader=dddddd&bgTextureHeader=flat&bgColorHeader=e9e9e9&cornerRadius=3px&fwDefault=normal&fsDefault=1em&ffDefault=Arial%2CHelvetica%2Csans-serif
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{text-align:left;border-width:2px}.ui-widget{font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666}
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jquery-ui.structure.min.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jquery-ui.structure.min.css
new file mode 100755
index 0000000000..723d9a342f
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/jquery-ui.structure.min.css
@@ -0,0 +1,24 @@
+/*! jQuery UI - v1.12.1 - 2017-10-31
+* http://jqueryui.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{border-width:2px}
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/logging.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/logging.css
new file mode 100755
index 0000000000..e28e771cfa
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/logging.css
@@ -0,0 +1,384 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #logging .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #logging .block h2
+{
+ background-image: url( ../../img/ico/document-text.png );
+ margin-bottom: 10px;
+}
+
+#content #logging .block h2 span span
+{
+ color: #c0c0c0;
+ font-weight: normal;
+ margin-left: 10px;
+}
+
+#content #logging #viewer
+{
+ position: relative;
+}
+
+#content #logging #viewer time
+{
+ white-space: pre;
+}
+
+#content #logging #viewer #footer
+{
+ margin-top: 20px;
+}
+
+#content #logging #viewer #state
+{
+ background-position: 0 50%;
+ float: left;
+ color: #4D4D4D;
+ width: 45%;
+}
+
+#content #logging #viewer #date-format
+{
+ float: right;
+}
+
+#content #logging #viewer #date-format a
+{
+ background-image: url( ../../img/ico/ui-check-box-uncheck.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ display: block;
+ padding-left: 21px;
+}
+
+#content #logging #viewer #date-format a:hover
+{
+ color: #008;
+}
+
+#content #logging #viewer #date-format a.on
+{
+ background-image: url( ../../img/ico/ui-check-box.png );
+ color: #333;
+}
+
+#content #logging #viewer #refresh-toggle {
+ background-position: 0 50%;
+ padding-left: 21px;
+ width:45%;
+}
+
+#content #logging #viewer #refresh-toggle.active {
+ background-image: url( ../../img/ico/cross-button.png );
+}
+
+#content #logging #viewer #refresh-toggle.stopped {
+ background-image: url( ../../img/ico/arrow-circle.png ) ;
+}
+
+#content #logging #viewer table
+{
+ border-collapse: collapse;
+ width: 100%;
+}
+
+#content #logging #viewer th,
+#content #logging #viewer td a,
+#content #logging #viewer tbody .trace td
+{
+ padding: 3px 10px;
+}
+
+#content #logging #viewer td
+{
+ vertical-align: top;
+}
+
+#content #logging #viewer td a
+{
+ display: block;
+}
+
+#content #logging #viewer thead th
+{
+ font-weight: bold;
+ text-align: left;
+}
+
+#content #logging #viewer tbody td,
+#content #logging #viewer tfoot td
+{
+ border-top: 1px solid #f0f0f0;
+}
+
+#content #logging #viewer thead th.message
+{
+ width:100%;
+}
+
+#content #logging #viewer tbody td.span a
+{
+ padding-left: 0;
+ padding-right: 0;
+}
+
+#content #logging #viewer tbody span
+{
+ display: block;
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#content #logging #viewer tbody .level-info .level span { background-color: #ebf5eb; }
+#content #logging #viewer tbody .level-warning span { background-color: #FFD930; }
+#content #logging #viewer tbody .level-severe span { background-color: #c43c35; color: #fff; }
+
+#content #logging #viewer tbody .level-debug span { background-color: #ebf5eb; }
+#content #logging #viewer tbody .level-warn span { background-color: #FFD930; }
+#content #logging #viewer tbody .level-error span { background-color: #FF6130; }
+#content #logging #viewer tbody .level-fatal span { background-color: #c43c35; }
+
+#content #logging #viewer tbody .has-trace a
+{
+ cursor: pointer;
+}
+
+#content #logging #viewer tbody .has-trace a:hover
+{
+ color: #008;
+}
+
+#content #logging #viewer tbody .has-trace .message a
+{
+ background-image: url( ../../img/ico/information.png );
+ background-position: 100% 50%;
+ display: block;
+ padding-right: 21px;
+}
+
+#content #logging #viewer tbody .has-trace.open .message a
+{
+ background-image: url( ../../img/ico/information-white.png );
+}
+
+#content #logging #viewer tbody .trace td
+{
+ border-top: 0;
+ color: #c0c0c0;
+}
+
+#content #logging #viewer tfoot td
+{
+ color: #4D4D4D;
+}
+
+#content #logging .jstree > li
+{
+ margin-left: 0;
+}
+
+#content #logging .jstree li
+{
+ position: relative;
+}
+
+#content #logging .jstree .level-finest { background-color: #d5e5fc; }
+#content #logging .jstree .level-fine { background-color: #d5fafc; }
+#content #logging .jstree .level-config { background-color: #e6fded; }
+#content #logging .jstree .level-info { background-color: #fafcd7; }
+#content #logging .jstree .level-warning { background-color: #fcecd5; }
+#content #logging .jstree .level-severe { background-color: #fcdcda; }
+#content #logging .jstree .level-off { background-color: #ffffff; }
+
+/* Log4j */
+#content #logging .jstree .level-all { background-color: #9EDAFF; }
+#content #logging .jstree .level-trace { background-color: #d5e5fc; }
+#content #logging .jstree .level-debug { background-color: #d5fafc; }
+#content #logging .jstree .level-warn { background-color: #e6fded; }
+#content #logging .jstree .level-error { background-color: #fcecd5; }
+#content #logging .jstree .level-fatal { background-color: #fcdcda; }
+
+
+#content #logging .jstree a
+{
+ height: 17px;
+ line-height: 17px;
+ padding: 0;
+ width: 90%;
+}
+
+#content #logging .jstree a:hover
+{
+ color: #008;
+}
+
+#content #logging .jstree a span.ns
+{
+ display: none;
+}
+
+#content #logging.ns .jstree a span.ns
+{
+ display: inline;
+}
+
+#content #logging .jstree a span.name
+{
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+}
+
+#content #logging .jstree a span.name em
+{
+ color: #f00;
+ font-style: normal;
+ text-transform: uppercase;
+}
+
+#content #logging .jstree a.trigger.set
+{
+ font-weight: bold;
+}
+
+#content #logging .jstree a:hover span.name
+{
+ background-image: url( ../../img/ico/pencil-small.png );
+}
+
+#content #logging .jstree .selector-holder
+{
+ position: absolute;
+ top: -2px;
+ z-index: 700;
+}
+
+#content #logging .jstree .selector-holder.open
+{
+ background-color: #fff;
+ margin-left: -19px;
+ z-index: 800;
+}
+
+#content #logging .jstree li .selector-holder { left: 440px; }
+#content #logging .jstree li li .selector-holder { left: 422px; }
+#content #logging .jstree li li li .selector-holder { left: 404px; }
+#content #logging .jstree li li li li .selector-holder { left: 386px; }
+#content #logging .jstree li li li li li .selector-holder { left: 368px; }
+#content #logging .jstree li li li li li li .selector-holder { left: 350px; }
+#content #logging .jstree li li li li li li li .selector-holder { left: 332px; }
+#content #logging .jstree li li li li li li li li .selector-holder { left: 314px; }
+
+#content #logging .jstree .selector
+{
+ border: 1px solid transparent;
+ position: relative;
+}
+
+#content #logging .jstree .open .selector
+{
+ border-color: #f0f0f0;
+ box-shadow: 5px 5px 10px #c0c0c0;
+ -moz-box-shadow: 5px 5px 10px #c0c0c0;
+ -webkit-box-shadow: 5px 5px 10px #c0c0c0;
+}
+
+#content #logging .jstree .selector a
+{
+ display: block;
+ padding: 2px;
+ width: auto;
+}
+
+#content #logging .jstree .open .selector .close
+{
+ background-image: url( ../../img/ico/cross-0.png );
+ background-position: 50% 50%;
+ display: block;
+ position: absolute;
+ right: -25px;
+ top: 0;
+ width: 20px;
+}
+
+#content #logging .jstree .open .selector .close:hover
+{
+ background-image: url( ../../img/ico/cross-1.png );
+}
+
+#content #logging .jstree .open .selector .close span
+{
+ display: none;
+}
+
+#content #logging .jstree .open .selector a.trigger
+{
+ display: none;
+}
+
+#content #logging .jstree .open .selector ul
+{
+ display: block;
+}
+
+#content #logging .jstree .selector ul li
+{
+ background: none;
+ margin-left: 0;
+}
+
+#content #logging .jstree .selector ul li a
+{
+ background-image: url( ../../img/ico/ui-radio-button-uncheck.png );
+ background-position: 2px 50%;
+ padding-left: 21px;
+}
+
+#content #logging .jstree .selector ul li a.level
+{
+ background-color: #f0f0f0;
+}
+
+#content #logging .jstree .selector ul li a:hover
+{
+ background-image: url( ../../img/ico/ui-radio-button.png );
+}
+
+#content #logging .jstree .selector li.unset
+{
+ border-top: 1px solid #f0f0f0;
+}
+
+#content #logging .jstree .selector li.unset a
+{
+ background-image: url( ../../img/ico/cross-0.png );
+ background-position: 4px 50%;
+}
+
+#content #logging .jstree .selector li.unset a:hover
+{
+ background-image: url( ../../img/ico/cross-1.png );
+ color: #800;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/login.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/login.css
new file mode 100755
index 0000000000..6d6c9083e2
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/login.css
@@ -0,0 +1,109 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #login
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+ vertical-align: center;
+ horiz-align: center;
+}
+
+#content #login h1,
+#content #login .h1 {
+ font-size: 2.5rem;
+}
+
+#content #login h2,
+#content #login .h2 {
+ font-size: 2rem;
+}
+
+#content #login p
+{
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+#content #login a
+{
+ color: #0000bf;
+ cursor: pointer;
+}
+
+#content #login .login-error
+{
+ font-size: 1rem;
+ color: red;
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+#content #login button {
+ border-radius: 0;
+}
+
+#content #login button:focus {
+ outline: 1px dotted;
+ outline: 5px auto -webkit-focus-ring-color;
+}
+
+#content #login .btn {
+ display: inline-block;
+ font-weight: 400;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ border: 1px solid transparent;
+ padding: 0.375rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border-radius: 0.25rem;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+
+#content #login .form-inline .form-group {
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ -ms-flex-flow: row wrap;
+ flex-flow: row wrap;
+ -ms-flex-align: center;
+ align-items: center;
+ margin-bottom: 0;
+}
+
+#content #login .form-control {
+ display: block;
+ width: 80%;
+ padding: 0.375rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ color: #495057;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid #ced4da;
+ border-radius: 0.25rem;
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/menu.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/menu.css
new file mode 100755
index 0000000000..4a24399bfd
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/menu.css
@@ -0,0 +1,330 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#menu-wrapper
+{
+ position: fixed;
+ top: 120px;
+ width: 150px;
+}
+
+.scroll #menu-wrapper
+{
+ position: absolute;
+ top: 90px;
+}
+
+.has-environment #menu-wrapper
+{
+ top: 160px;
+}
+
+#menu-wrapper a
+{
+ display: block;
+ padding: 4px 2px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+#core-selector,#collection-selector
+{
+ margin-top: 20px;
+ padding-right: 10px;
+}
+
+#core-selector a,
+#collection-selector a
+{
+ padding: 0;
+ padding-left: 8px;
+}
+
+#core-selector select,
+#collection-selector select
+{
+ width: 100%;
+}
+
+#core-selector #has-no-cores a,
+#collection-selector #has-no-collections a
+{
+ background-image: url( ../../img/ico/database--plus.png );
+}
+
+#core-selector #has-no-cores span,
+#collection-selector #has-no-collections span
+{
+ color: #8D8D8D;
+ display: block;
+}
+
+#menu-wrapper .active p
+{
+ background-color: #fafafa;
+ border-color: #c0c0c0;
+}
+
+#menu-wrapper p a,
+#menu a
+{
+ background-position: 5px 50%;
+ padding-left: 26px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+#menu-wrapper p a:hover
+{
+ background-color: #f0f0f0;
+}
+
+#menu-wrapper .active p a
+{
+ background-color: #c0c0c0;
+ font-weight: bold;
+}
+
+#menu p.loader
+{
+ background-position: 5px 50%;
+ color: #c0c0c0;
+ margin-top: 5px;
+ padding-left: 26px;
+}
+
+#menu p a small
+{
+ color: #b5b5b5;
+ font-weight: normal;
+}
+
+#menu p a small span.txt
+{
+}
+
+#menu p a small:hover span.txt
+{
+ display: inline;
+}
+
+#menu .busy
+{
+ border-right-color: #f6f5d9;
+}
+
+#menu .busy p a
+{
+ background-color: #f6f5d9;
+ background-image: url( ../../img/ico/status-away.png );
+}
+
+#menu .offline
+{
+ border-right-color: #eccfcf;
+}
+
+#menu .offline p a
+{
+ background-color: #eccfcf;
+ background-image: url( ../../img/ico/status-busy.png );
+}
+
+#menu .online
+{
+ border-right-color: #cfecd3;
+}
+
+#menu .online p a
+{
+ background-color: #cfecd3;
+ background-image: url( ../../img/ico/status.png );
+}
+
+#menu .ping small
+{
+ color: #000
+}
+
+#menu li
+{
+ border-bottom: 1px solid #f0f0f0;
+}
+
+#menu li:last-child
+{
+ border-bottom: 0;
+}
+
+#menu li.optional
+{
+}
+
+.sub-menu p
+{
+ border-top: 1px solid #f0f0f0;
+}
+
+.sub-menu li:first-child p
+{
+ border-top: 0;
+}
+
+.sub-menu p a
+{
+ background-image: url( ../../img/ico/status-offline.png );
+}
+
+.sub-menu .active p a
+{
+ background-image: url( ../../img/ico/box.png );
+}
+
+.sub-menu ul,
+#menu ul
+{
+ padding-top: 5px;
+ padding-bottom: 10px;
+}
+
+.sub-menu .active ul,
+#menu .active ul
+{
+ display: block;
+}
+
+#menu ul li
+{
+ border-bottom: 0;
+}
+
+#core-menu ul li a,
+#collection-menu ul li a,
+#menu ul li a
+{
+ background-position: 7px 50%;
+ border-bottom: 1px solid #f0f0f0;
+ margin-left: 15px;
+ padding-left: 26px;
+}
+
+.sub-menu ul li:last-child a,
+#menu ul li:last-child a
+{
+ border-bottom: 0;
+}
+
+.sub-menu ul li a:hover,
+#menu ul li a:hover
+{
+ background-color: #f0f0f0;
+ color: #333;
+}
+
+.sub-menu ul li.active a,
+#menu ul li.active a
+{
+ background-color: #d0d0d0;
+ border-color: #d0d0d0;
+ color: #FFF;
+}
+
+#menu #index.global p a { background-image: url( ../../img/ico/dashboard.png ); }
+
+#menu #login.global p a { background-image: url( ../../img/ico/users.png ); }
+
+#menu #logging.global p a { background-image: url( ../../img/ico/inbox-document-text.png ); }
+#menu #logging.global .level a { background-image: url( ../../img/ico/gear.png ); }
+
+#menu #java-properties.global p a { background-image: url( ../../img/ico/jar.png ); }
+
+#menu #threads.global p a { background-image: url( ../../img/ico/ui-accordion.png ); }
+
+#menu #collections.global p a { background-image: url( ../../img/ico/documents-stack.png ); }
+#menu #cores.global p a { background-image: url( ../../img/ico/databases.png ); }
+#menu #cluster-suggestions.global p a { background-image: url( ../../img/ico/idea.png ); }
+
+#menu #cloud.global p a { background-image: url( ../../img/ico/network-cloud.png ); }
+#menu #cloud.global .tree a { background-image: url( ../../img/ico/folder-tree.png ); }
+#menu #cloud.global .nodes a { background-image: url( ../../img/solr-ico.png ); }
+#menu #cloud.global .zkstatus a { background-image: url( ../../img/ico/node-master.png ); }
+#menu #cloud.global .graph a { background-image: url( ../../img/ico/molecule.png ); }
+
+.sub-menu .ping.error a
+{
+
+ background-color: #ffcccc;
+ background-image: url( ../../img/ico/system-monitor--exclamation.png );
+ border-color: #ffcccc;
+ cursor: help;
+}
+
+.sub-menu .overview a { background-image: url( ../../img/ico/home.png ); }
+.sub-menu .query a { background-image: url( ../../img/ico/magnifier.png ); }
+.sub-menu .stream a { background-image: url( ../../img/ico/node.png ); }
+.sub-menu .analysis a { background-image: url( ../../img/ico/funnel.png ); }
+.sub-menu .documents a { background-image: url( ../../img/ico/documents-stack.png ); }
+.sub-menu .files a { background-image: url( ../../img/ico/folder.png ); }
+.sub-menu .schema a { background-image: url( ../../img/ico/book-open-text.png ); }
+.sub-menu .replication a { background-image: url( ../../img/ico/node.png ); }
+.sub-menu .distribution a { background-image: url( ../../img/ico/node-select.png ); }
+.sub-menu .ping a { background-image: url( ../../img/ico/system-monitor.png ); }
+.sub-menu .logging a { background-image: url( ../../img/ico/inbox-document-text.png ); }
+.sub-menu .plugins a { background-image: url( ../../img/ico/block.png ); }
+.sub-menu .dataimport a { background-image: url( ../../img/ico/document-import.png ); }
+.sub-menu .segments a { background-image: url( ../../img/ico/construction.png ); }
+
+
+#content #navigation
+{
+ border-right: 1px solid #e0e0e0;
+}
+
+#content #navigation a
+{
+ display: block;
+ padding: 4px 2px;
+}
+
+#content #navigation .current
+{
+ border-color: #e0e0e0;
+}
+
+#content #navigation a
+{
+ background-position: 5px 50%;
+ padding-left: 26px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+#content #navigation a:hover
+{
+ background-color: #f0f0f0;
+}
+
+#content #navigation .current a
+{
+ background-color: #e0e0e0;
+ font-weight: bold;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/plugins.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/plugins.css
new file mode 100755
index 0000000000..e4398bda20
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/plugins.css
@@ -0,0 +1,220 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #plugins #navigation
+{
+ width: 20%;
+}
+
+#content #plugins #navigation .cache a { background-image: url( ../../img/ico/disk-black.png ); }
+#content #plugins #navigation .core a { background-image: url( ../../img/ico/wooden-box.png ); }
+#content #plugins #navigation .other a { background-image: url( ../../img/ico/zone.png ); }
+#content #plugins #navigation .highlighting a { background-image: url( ../../img/ico/highlighter-text.png ); }
+#content #plugins #navigation .updatehandler a{ background-image: url( ../../img/ico/arrow-circle.png ); }
+#content #plugins #navigation .queryhandler a { background-image: url( ../../img/ico/magnifier.png ); }
+#content #plugins #navigation .queryparser a { background-image: url( ../../img/ico/asterisk.png ); }
+
+#content #plugins #navigation .PLUGINCHANGES { margin-top: 20px; }
+#content #plugins #navigation .PLUGINCHANGES a { background-image: url( ../../img/ico/eye.png ); }
+#content #plugins #navigation .RELOAD a { background-image: url( ../../img/ico/arrow-circle.png ); }
+#content #plugins #navigation .NOTE { margin-top: 20px; }
+#content #plugins #navigation .NOTE p { color: #4D4D4D; font-style: italic; }
+
+
+#content #plugins #navigation a
+{
+ position: relative;
+}
+
+#content #plugins #navigation a span
+{
+ background-color: #bba500;
+ border-radius: 5px;
+ color: #fff;
+ font-size: 10px;
+ font-weight: normal;
+ line-height: 1.4em;
+ padding-left: 4px;
+ padding-right: 4px;
+ position: absolute;
+ right: 5px;
+ top: 7px;
+}
+
+#content #plugins #frame
+{
+ float: right;
+ width: 78%;
+}
+
+#content #plugins #frame .entry
+{
+ margin-bottom: 10px;
+}
+
+#content #plugins #frame .entry:last-child
+{
+ margin-bottom: 0;
+}
+
+#content #plugins #frame .entry a
+{
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ background-position: 0 50%;
+ display: block;
+ font-weight: bold;
+ padding-left: 21px;
+}
+
+#content #plugins #frame .entry.changed a span
+{
+ color: #bba500;
+}
+
+#content #plugins #frame .entry.expanded a
+{
+ background-image: url( ../../img/ico/chevron-small.png );
+}
+
+#content #plugins #frame .entry.expanded ul
+{
+ display: block;
+}
+
+#content #plugins #frame .entry ul
+{
+ border-left: 9px solid #f0f3ff;
+ margin-left: 3px;
+ padding-top: 5px;
+ padding-left: 10px;
+}
+
+#content #plugins #frame .entry li
+{
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+
+#content #plugins #frame .entry li.stats
+{
+ border-top: 1px solid #c0c0c0;
+ margin-top: 5px;
+ padding-top: 5px;
+}
+
+#content #plugins #frame .entry li.odd
+{
+ background-color: #f8f8f8;
+}
+
+#content #plugins #frame .entry dt,
+#content #plugins #frame .entry .stats span
+{
+ float: left;
+ width: 9%;
+}
+
+#content #plugins #frame .entry dd,
+#content #plugins #frame .entry .stats ul
+{
+ float: right;
+ width: 90%;
+}
+
+#content #plugins #frame .entry .stats ul
+{
+ border-left: 0;
+ margin: 0;
+ padding: 0;
+}
+
+#content #plugins #frame .entry .stats dt
+{
+ width: 40%;
+}
+
+#content #plugins #frame .entry .stats dd
+{
+ width: 59%;
+}
+
+#content #plugins #frame .entry.expanded a.linker {
+ background-image: none;
+ background-position: 0 0;
+ display: inline;
+ font-weight: normal;
+ padding:0px;
+}
+
+#content #plugins #frame .entry.expanded a.linker:hover {
+ background-color:#F0F3FF;
+}
+
+#content #plugins .active a
+{
+ background-color: #d0d0d0;
+ border-color: #d0d0d0;
+}
+
+#recording #blockUI
+{
+ position: absolute;
+ left:0;
+ top:0;
+ width: 100%;
+ height: 100%;
+ background-color: #000;
+ opacity: 0.6;
+ z-index:1000;
+ padding:0;
+}
+
+#recording .wrapper
+{
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ padding: 30px;
+ width: 415px;
+ height: 100px;
+ border: 2px solid black;
+ background-color: #FFF;
+ opacity: 1;
+ z-index: 2000;
+ transform: translate(-50%, -50%);
+}
+
+#recording p
+{
+ background-position: 0 50%;
+ float: left;
+ padding-left: 21px;
+ padding-top: 7px;
+ padding-bottom: 7px;
+}
+
+#recording button
+{
+ float: right;
+}
+
+#recording button span
+{
+ background-image: url( ../../img/ico/new-text.png );
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/query.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/query.css
new file mode 100755
index 0000000000..be264bf9bf
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/query.css
@@ -0,0 +1,162 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #query
+{
+ background-image: url( ../../img/div.gif );
+ background-position: 22% 0;
+ background-repeat: repeat-y;
+}
+
+#content #query #form
+{
+ float: left;
+ width: 21%;
+}
+
+#content #query #form label
+{
+ cursor: pointer;
+ display: block;
+ margin-top: 5px;
+}
+
+#content #query #form input,
+#content #query #form select,
+#content #query #form textarea
+{
+ margin-bottom: 2px;
+ width: 100%;
+}
+
+#content #query #form input,
+#content #query #form textarea
+{
+ width: 98%;
+}
+
+#content #query #form .multiple input
+{
+ float: left;
+ width: 80%
+}
+
+#content #query #form .multiple .buttons
+{
+ float: right;
+ width: 16%;
+}
+
+
+#content #query #form .multiple a
+{
+ background-position: 50% 50%;
+ display: block;
+ height: 25px;
+ width: 49%;
+}
+
+#content #query #form .multiple a.add
+{
+ background-image: url( ../../img/ico/plus-button.png );
+ float: right;
+}
+
+#content #query #form .multiple a.rem
+{
+ background-image: url( ../../img/ico/minus-button.png );
+ float: left;
+}
+
+#content #query #form #start
+{
+ float: left;
+ width: 45%;
+}
+
+#content #query #form #rows
+{
+ float: right;
+ width: 45%;
+}
+
+#content #query #form .checkbox input
+{
+ margin-bottom: 0;
+ width: auto;
+}
+
+#content #query #form fieldset,
+#content #query #form .optional.expanded
+{
+ border: 1px solid #fff;
+ border-top: 1px solid #c0c0c0;
+ margin-bottom: 5px;
+}
+
+#content #query #form fieldset.common
+{
+ margin-top: 10px;
+}
+
+#content #query #form fieldset legend,
+#content #query #form .optional.expanded legend
+{
+ display: block;
+ margin-left: 10px;
+ padding: 0px 5px;
+}
+
+#content #query #form fieldset legend label
+{
+ margin-top: 0;
+}
+
+#content #query #form fieldset .fieldset
+{
+ border-bottom: 1px solid #f0f0f0;
+ margin-bottom: 5px;
+ padding-bottom: 10px;
+}
+
+#content #query #form .optional
+{
+ border: 0;
+}
+
+#content #query #form .optional legend
+{
+ margin-left: 0;
+ padding-left: 0;
+}
+
+#content #query #form .optional.expanded .fieldset
+{
+ display: block;
+}
+
+#content #query #result
+{
+ float: right;
+ width: 77%;
+}
+
+#content #query #result #response
+{
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/replication.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/replication.css
new file mode 100755
index 0000000000..4eb608878d
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/replication.css
@@ -0,0 +1,500 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #replication
+{
+ background-image: url( ../../img/div.gif );
+ background-position: 21% 0;
+ background-repeat: repeat-y;
+}
+
+#content #replication #frame
+{
+ float: right;
+ width: 78%;
+}
+
+#content #replication #navigation
+{
+ border-right: 0;
+ float: left;
+ width: 20%;
+}
+
+#content #replication #error
+{
+ background-color: #f00;
+ background-image: url( ../../img/ico/construction.png );
+ background-position: 10px 50%;
+ color: #fff;
+ font-weight: bold;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+}
+
+#content #replication .block
+{
+ border-bottom: 1px solid #c0c0c0;
+ margin-bottom: 20px;
+ padding-bottom: 20px;
+}
+
+#content #replication .block.last
+{
+ border-bottom: 0;
+}
+
+#content #replication .masterOnly,
+#content #replication .slaveOnly
+{
+}
+
+#content #replication.master .masterOnly
+{
+ display: block;
+}
+
+#content #replication.slave .slaveOnly
+{
+ display: block;
+}
+
+#content #replication .replicating
+{
+}
+
+#content #replication.replicating .replicating
+{
+ display: block;
+}
+
+#content #replication #progress
+{
+ padding-bottom: 80px;
+ position: relative;
+}
+
+#content #replication #progress .info
+{
+ padding: 5px;
+}
+
+#content #replication #progress #start
+{
+ margin-left: 100px;
+ border-left: 1px solid #c0c0c0;
+}
+
+#content #replication #progress #bar
+{
+ background-color: #f0f0f0;
+ margin-left: 100px;
+ margin-right: 100px;
+ position: relative;
+}
+
+#content #replication #progress #bar #bar-info,
+#content #replication #progress #bar #eta
+{
+ position: absolute;
+ right: -100px;
+ width: 100px;
+}
+
+#content #replication #progress #bar #bar-info
+{
+ border-left: 1px solid #f0f0f0;
+ margin-top: 30px;
+}
+
+#content #replication #progress #eta .info
+{
+ color: #4D4D4D;
+ height: 30px;
+ line-height: 30px;
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+#content #replication #progress #speed
+{
+ color: #4D4D4D;
+ position: absolute;
+ right: 100px;
+ top: 0;
+}
+
+#content #replication #progress #bar #done
+{
+ background-color: #4D4D4D;
+ box-shadow: 5px 5px 10px #c0c0c0;
+ -moz-box-shadow: 5px 5px 10px #c0c0c0;
+ -webkit-box-shadow: 5px 5px 10px #c0c0c0;
+ height: 30px;
+ position: relative;
+}
+
+#content #replication #progress #bar #done .percent
+{
+ font-weight: bold;
+ height: 30px;
+ line-height: 30px;
+ padding-left: 5px;
+ padding-right: 5px;
+ position: absolute;
+ right: 0;
+ text-align: right;
+}
+
+#content #replication #progress #bar #done #done-info
+{
+ border-right: 1px solid #c0c0c0;
+ position: absolute;
+ right: 0;
+ margin-top: 30px;
+ text-align: right;
+ width: 100px;
+}
+
+#content #replication #progress #bar #done #done-info .percent
+{
+ font-weight: bold;
+}
+
+#content #replication .block .label,
+#content #replication #current-file .file,
+#content #replication #current-file .progress,
+#content #replication #iterations .iterations
+{
+ float: left;
+}
+
+#content #replication .block .label
+{
+ width: 100px;
+}
+
+#content #replication .block .label span
+{
+ display: block;
+ padding-left: 21px;
+}
+
+#content #replication #current-file
+{
+ border-top: 1px solid #f0f0f0;
+ margin-top: 10px;
+ padding-top: 10px;
+}
+
+#content #replication #current-file .progress
+{
+ color: #4D4D4D;
+ margin-left: 20px;
+}
+
+#content #replication #iterations .label span
+{
+ background-image: url( ../../img/ico/node-design.png );
+}
+
+#content #replication #iterations .iterations li
+{
+ background-position: 100% 50%;
+ padding-right: 21px;
+}
+
+#content #replication #iterations .iterations.expanded li
+{
+ display: block;
+}
+
+#content #replication #iterations .iterations .latest
+{
+ display: block;
+}
+
+#content #replication #iterations .iterations .replicated
+{
+ color: #80c480;
+}
+
+#content #replication #iterations .iterations ul:hover .replicated,
+#content #replication #iterations .iterations .replicated.latest
+{
+ color: #080;
+}
+
+#content #replication #iterations .iterations .replicated.latest
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #replication #iterations .iterations .failed
+{
+ color: #c48080;
+}
+
+#content #replication #iterations .iterations ul:hover .failed,
+#content #replication #iterations .iterations .failed.latest
+{
+ color: #800;
+}
+
+#content #replication #iterations .iterations .failed.latest
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #replication #iterations .iterations a
+{
+ border-top: 1px solid #f0f0f0;
+ margin-top: 2px;
+ padding-top: 2px;
+}
+
+#content #replication #iterations .iterations a span
+{
+ background-position: 0 50%;
+ color: #4D4D4D;
+ padding-left: 21px;
+}
+
+#content #replication #iterations .iterations a span.expand
+{
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ display: block;
+}
+
+#content #replication #iterations .iterations a span.collapse
+{
+ background-image: url( ../../img/ico/chevron-small.png );
+ display: block;
+}
+
+#content #replication #details table
+{
+ margin-left: 20px;
+ border-collapse: collapse;
+}
+
+#content #replication #details table th
+{
+ text-align: left;
+}
+
+#content #replication.slave #details table .slaveOnly
+{
+ display: table-row;
+}
+
+#content #replication #details table thead th
+{
+ color: #4D4D4D;
+}
+
+#content #replication #details table thead th,
+#content #replication #details table tbody td
+{
+ padding-right: 20px;
+}
+
+#content #replication #details table thead td,
+#content #replication #details table thead th,
+#content #replication #details table tbody th,
+#content #replication #details table tbody td div
+{
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+#content #replication #details table tbody td,
+#content #replication #details table tbody th
+{
+ border-top: 1px solid #f0f0f0;
+}
+
+#content #replication #details table thead td
+{
+ width: 100px;
+}
+
+#content #replication #details table thead td span
+{
+ background-image: url( ../../img/ico/clipboard-list.png );
+ background-position: 0 50%;
+ display: block;
+ padding-left: 21px;
+}
+
+#content #replication #details table tbody th
+{
+ padding-right: 10px;
+ text-align: right;
+ white-space: nowrap;
+}
+
+#content #replication #details table tbody .size
+{
+ text-align: right;
+ white-space: nowrap;
+}
+
+#content #replication #details table tbody .generation div
+{
+ text-align: center;
+}
+
+#content #replication #details table tbody .diff div
+{
+ background-color: #fcfcc9;
+ padding-left: 1px;
+ padding-right: 1px;
+}
+
+#content #replication .settings .label span
+{
+ background-image: url( ../../img/ico/hammer-screwdriver.png );
+}
+
+#content #replication .settings ul,
+#content #replication .settings dl dt,
+#content #replication .settings dl dd
+{
+ float: left;
+}
+
+#content #replication .settings ul li
+{
+ border-top: 1px solid #f0f0f0;
+ padding-top: 3px;
+ padding-top: 3px;
+}
+
+#content #replication .settings ul li:first-child
+{
+ border-top: 0;
+ padding-top: 0;
+}
+
+#content #replication .settings dl dt
+{
+ clear: left;
+ margin-right: 5px;
+ width: 120px;
+}
+
+#content #replication .settings dl .ico
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #replication .settings dl .ico.ico-0
+{
+ background-image: url( ../../img/ico/slash.png );
+}
+
+#content #replication .settings dl .ico.ico-1
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #replication .timer
+{
+ box-shadow: 5px 5px 10px #c0c0c0;
+ -moz-box-shadow: 5px 5px 10px #c0c0c0;
+ -webkit-box-shadow: 5px 5px 10px #c0c0c0;
+ margin-bottom: 20px;
+ padding: 10px;
+}
+
+#content #replication .timer p,
+#content #replication .timer small
+{
+ padding-left: 21px;
+}
+
+#content #replication .timer p
+{
+ background-image: url( ../../img/ico/clock-select-remain.png );
+ background-position: 0 50%;
+}
+
+#content #replication .timer p .approx
+{
+ color: #4D4D4D;
+ margin-right: 1px;
+}
+
+#content #replication .timer p .tick
+{
+ font-weight: bold;
+}
+
+#content #replication .timer small
+{
+ color: #4D4D4D;
+}
+
+#content #replication #navigation button
+{
+ display: block;
+ margin-bottom: 10px;
+}
+
+#content #replication #navigation button.optional
+{
+}
+
+#content #replication #navigation .replicate-now span
+{
+ background-image: url( ../../img/ico/document-convert.png );
+}
+
+#content #replication #navigation .abort-replication span
+{
+ background-image: url( ../../img/ico/hand.png );
+}
+
+#content #replication #navigation .disable-polling span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #replication #navigation .enable-polling span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #replication #navigation .disable-replication span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #replication #navigation .enable-replication span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #replication #navigation .refresh-status span
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/schema.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/schema.css
new file mode 100755
index 0000000000..05d947890a
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/schema.css
@@ -0,0 +1,727 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #schema .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #schema.loaded
+{
+ background-image: url( ../../img/div.gif );
+ background-position: 21% 0;
+ background-repeat: repeat-y;
+}
+
+#content #schema #data
+{
+ float: right;
+ width: 78%;
+}
+
+#content #schema #related
+{
+ float: left;
+ width: 20%;
+}
+
+#content #schema #related select
+{
+ width: 100%;
+}
+
+#content #schema #related select optgroup
+{
+ font-style: normal;
+ padding: 5px;
+}
+
+#content #schema #related select option
+{
+ padding-left: 10px;
+}
+
+#content #schema #related #f-df-t
+{
+ border-bottom: 1px solid #f0f0f0;
+ padding-bottom: 15px;
+}
+
+#content #schema #related .ukf-dsf dt
+{
+}
+
+#content #schema #related dl
+{
+ margin-top: 15px;
+}
+
+#content #schema #related dl dt,
+#content #schema #related dl dd a
+{
+ color: #4D4D4D;
+}
+
+#content #schema #related dl dt
+{
+ font-weight: bold;
+ margin-top: 5px;
+}
+
+#content #schema #related dl dd a
+{
+ display: block;
+ padding-left: 10px;
+}
+
+#content #schema #related dl dd a:hover
+{
+ background-color: #f8f8f8;
+}
+
+#content #schema #related .field .field,
+#content #schema #related .field .field a,
+#content #schema #related .dynamic-field .dynamic-field,
+#content #schema #related .dynamic-field .dynamic-field a,
+#content #schema #related .type .type,
+#content #schema #related .type .type a,
+#content #schema #related .active,
+#content #schema #related .active a
+{
+ color: #333;
+}
+
+#content #schema #related .copyfield,
+#content #schema #related .copyfield a
+{
+ color: #666;
+}
+
+#content #schema #data
+{
+}
+
+#content #schema #data #index dt
+{
+ float: left;
+ margin-right: 5px;
+ width: 150px;
+}
+
+#content #schema #data #field .field-options
+{
+ margin-bottom: 10px;
+}
+
+#content #schema #data #field .field-options .head h2
+{
+ padding-left: 5px;
+}
+
+#content #schema #data #field .partial
+{
+}
+
+#content #schema #data #field .partial p
+{
+ background-image: url( ../../img/ico/exclamation-button.png );
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #schema #data #field .field-options .options dt,
+#content #schema #data #field .field-options .options dd
+{
+ float: left;
+}
+
+#content #schema #data #field .field-options .options dt
+{
+ clear: left;
+ margin-right: 5px;
+ width: 100px;
+}
+
+#content #schema #data #field .field-options .flags
+{
+ margin-top: 10px;
+ margin-bottom: 20px;
+}
+
+#content #schema #data #field .field-options .flags thead td
+{
+ color: #4D4D4D;
+ padding-right: 5px;
+ width: 100px;
+}
+
+#content #schema #data #field .field-options .flags tbody td,
+#content #schema #data #field .field-options .flags th
+{
+ padding: 2px 5px;
+}
+
+#content #schema #data #field .field-options .flags thead td,
+#content #schema #data #field .field-options .flags tbody th
+{
+ padding-left: 0;
+}
+
+#content #schema #data #field .field-options .flags thead th,
+#content #schema #data #field .field-options .flags tbody td
+{
+ border-left: 1px solid #f0f0f0;
+}
+
+#content #schema #data #field .field-options .flags tbody th,
+#content #schema #data #field .field-options .flags tbody td
+{
+ border-top: 1px solid #f0f0f0;
+}
+
+#content #schema #data #field .field-options .flags tbody .check
+{
+ background-color: #fafdfa;
+ background-image: url( ../../img/ico/tick.png );
+ background-position: 50% 50%;
+ text-align: center;
+}
+
+#content #schema #data #field .field-options .flags tbody .check span
+{
+}
+
+#content #schema #data #field .field-options .flags tbody .text
+{
+ color: #4D4D4D;
+}
+
+#content #schema #data #field .field-options .analyzer,
+#content #schema #data #field .field-options .analyzer li,
+#content #schema #data #field .field-options .analyzer ul,
+#content #schema #data #field .field-options .analyzer ul li
+{
+}
+
+#content #schema #data #field .field-options .analyzer p,
+#content #schema #data #field .field-options .analyzer dl
+{
+ float: left;
+}
+
+#content #schema #data #field .field-options .analyzer p
+{
+ margin-right: 5px;
+ text-align: right;
+ width: 125px;
+ white-space: pre;
+}
+
+#content #schema #data #field .field-options .analyzer p a
+{
+ cursor: auto;
+}
+
+#content #schema #data #field .field-options .analyzer p a.analysis
+{
+ cursor: pointer;
+ display: block;
+}
+
+#content #schema #data #field .field-options .analyzer p a.analysis span
+{
+ background-image: url( ../../img/ico/question-white.png );
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #schema #data #field .field-options .analyzer p a.analysis:hover span
+{
+ background-image: url( ../../img/ico/question.png );
+ color: #008;
+}
+
+#content #schema #data #field .field-options .analyzer a
+{
+ cursor: auto;
+}
+
+#content #schema #data #field .field-options .analyzer .toggle
+{
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ display: block;
+ padding-right: 21px;
+}
+
+#content #schema #data #field .field-options .analyzer .open .toggle
+{
+ background-image: url( ../../img/ico/chevron-small.png );
+}
+
+#content #schema #data #field .field-options .analyzer li
+{
+ border-top: 1px solid #f0f0f0;
+ margin-top: 10px;
+ padding-top: 10px;
+}
+
+#content #schema #data #field .field-options .analyzer ul
+{
+ clear: left;
+ margin-left: 55px;
+ padding-top: 5px;
+}
+
+#content #schema #data #field .field-options .analyzer .open ul
+{
+ display: block;
+}
+
+#content #schema #data #field .field-options .analyzer ul li
+{
+ border-top: 1px solid #f8f8f8;
+ margin-top: 5px;
+ padding-top: 5px;
+}
+
+#content #schema #data #field .field-options .analyzer ul p
+{
+ color: #4D4D4D;
+ margin-right: 5px;
+ text-align: right;
+ width: 70px;
+}
+
+#content #schema #data #field .field-options .analyzer ul dd
+{
+ margin-left: 20px;
+}
+
+#content #schema #data #field .field-options .analyzer ul dd
+{
+ background-image: url( ../../img/ico/document-list.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ padding-left: 21px;
+}
+
+#content #schema #data #field .field-options .analyzer ul dd.ico-0
+{
+ background-image: url( ../../img/ico/slash.png );
+}
+
+#content #schema #data #field .field-options .analyzer ul dd.ico-1
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #schema #data #field .head
+{
+ margin-bottom: 5px;
+}
+
+#content #schema #data #field .terminfo-holder
+{
+ border-top: 1px solid #c0c0c0;
+ padding-top: 10px;
+}
+
+#content #schema #data #field .terminfo-holder .trigger
+{
+ float: left;
+ width: 140px;
+}
+
+#content #schema #data #field .terminfo-holder .trigger button span
+{
+ background-image: url( ../../img/ico/information.png );
+}
+
+#content #schema #data #field .terminfo-holder .status
+{
+ border-left: 1px solid #f0f0f0;
+ float: left;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+
+#content #schema #data #field .terminfo-holder.disabled .trigger button span
+{
+ background-image: url( ../../img/ico/prohibition.png );
+}
+
+#content #schema #data #field .terminfo-holder.disabled .status
+{
+ display: block;
+}
+
+#content #schema #data #field .terminfo-holder .trigger .autoload
+{
+}
+
+#content #schema #data #field .terminfo-holder.loaded .trigger .autoload
+{
+ background-image: url( ../../img/ico/ui-check-box-uncheck.png );
+ background-position: 0 50%;
+ color: #8D8D8D;
+ display: block;
+ margin-top: 10px;
+ padding-left: 21px;
+}
+
+#content #schema #data #field .terminfo-holder .trigger .autoload:hover
+{
+ color: #008;
+}
+
+#content #schema #data #field .terminfo-holder .trigger .autoload.on
+{
+ background-image: url( ../../img/ico/ui-check-box.png );
+ color: #333;
+}
+
+#content #schema #data #field .topterms-holder,
+#content #schema #data #field .histogram-holder
+{
+ border-left: 1px solid #f0f0f0;
+ float: left;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+
+#content #schema #data #field .topterms-holder .head input
+{
+ height: 18px;
+ line-height: 16px;
+ text-align: right;
+ width: 30px;
+}
+
+#content #schema #data #field .topterms-holder .head .max-holder
+{
+ color: #4D4D4D;
+}
+
+#content #schema #data #field .topterms-holder .head .max-holder:hover .max
+{
+ color: #008;
+}
+
+#content #schema #data #field .topterms-holder .head #query_link
+{
+ background-image: url( ../../img/ico/question-white.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ padding-left: 21px;
+ margin-left: 5px;
+}
+
+#content #schema #data #field .topterms-holder .head #query_link:hover
+{
+ background-image: url( ../../img/ico/question.png );
+}
+
+
+#content #schema #data #field .topterms-holder .head #query_link span
+{
+ visibility: hidden;
+}
+
+#content #schema #data #field .topterms-holder .head #query_link:hover span
+{
+ visibility: visible;
+}
+
+#content #schema .topterms-holder li
+{
+ border-top: 1px solid #999;
+ margin-bottom: 5px;
+}
+
+/* possible overwrite with inline style */
+#content #schema .topterms-holder li p
+{
+ background-color: #999;
+ color: #fff;
+ float: left;
+}
+
+#content #schema .topterms-holder li p span
+{
+ display: block;
+ padding-right: 2px;
+ text-align: right;
+}
+
+/* possible overwrite with inline style */
+#content #schema .topterms-holder li ul
+{
+ margin-left: 30px;
+}
+
+#content #schema .topterms-holder li li
+{
+ border-top: 0;
+ margin-bottom: 0;
+ white-space: nowrap;
+}
+
+#content #schema .topterms-holder li li.odd
+{
+ background-color: #f0f0f0;
+}
+
+#content #schema .topterms-holder li li a
+{
+ display: block;
+ padding-left: 2px;
+ padding-right: 2px;
+}
+
+#content #schema .topterms-holder li li a:hover
+{
+ background-color: #c0c0c0;
+}
+
+#content #schema #data #field .histogram-holder ul
+{
+ margin-left: 25px;
+}
+
+#content #schema #data #field .histogram-holder li
+{
+ margin-bottom: 2px;
+ position: relative;
+ width: 150px;
+}
+
+#content #schema #data #field .histogram-holder li.odd
+{
+ background-color: #f0f0f0;
+}
+
+#content #schema #data #field .histogram-holder li dl,
+#content #schema #data #field .histogram-holder li dt
+{
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
+#content #schema #data #field .histogram-holder li dl
+{
+ background-color: #c0c0c0;
+ min-width: 1px;
+}
+
+#content #schema #data #field .histogram-holder li dt
+{
+ color: #a0a0a0;
+ position: absolute;
+ overflow: hidden;
+ left: -25px;
+ top: 0px;
+}
+
+#content #schema #data #field .histogram-holder li dt span
+{
+ display: block;
+ padding-right: 4px;
+ text-align: right;
+}
+
+#content #schema #data #field .histogram-holder li dd
+{
+ clear: left;
+ float: left;
+ margin-left: 2px;
+ white-space: nowrap;
+}
+
+#content #schema #data #field .histogram-holder li:hover dl
+{
+ background-color: #b0b0b0;
+}
+
+#content #schema #data #field .histogram-holder li:hover dt
+{
+ color: #333;
+}
+
+#content #schema #actions {
+ margin-bottom: 20px;
+ min-height: 30px;
+}
+
+#content #schema .actions #addField span { background-image: url( ../../img/ico/document-list.png ); }
+#content #schema .actions #addDynamicField span { background-image: url( ../../img/ico/documents-stack.png ); }
+#content #schema .actions #addCopyField span { background-image: url( ../../img/ico/document-import.png ); }
+
+#content #schema .actions div.action
+{
+ width: 320px;
+ background-color: #fff;
+ border: 1px solid #f0f0f0;
+ box-shadow: 5px 5px 10px #c0c0c0;
+ -moz-box-shadow: 5px 5px 10px #c0c0c0;
+ -webkit-box-shadow: 5px 5px 10px #c0c0c0;
+ position: absolute;
+ left: 160px;
+ top: 50px;
+ padding: 10px;
+ z-index: 2;
+}
+
+#content #schema .actions p
+{
+ padding-bottom: 8px;
+}
+
+#content #schema .actions label
+{
+ float: left;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ text-align: right;
+ width: 25%;
+}
+
+#content #schema .actions input,
+#content #schema .actions select,
+#content #schema .actions .buttons,
+#content #schema .actions .note span
+{
+ float: right;
+ width: 71%;
+}
+
+#content #schema .actions label.checkbox {
+ margin-left: 27%;
+ text-align: left;
+ width: 73%;
+ padding: 0px;
+ margin-top: 0px;
+}
+#content #schema .actions .checkbox input {
+ float: none;
+ width: auto;
+}
+
+#content #schema .add_showhide {
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+}
+
+#content #schema .add_showhide.open {
+ background-image: url( ../../img/ico/chevron-small.png );
+}
+
+#content #schema label
+{
+ cursor: pointer;
+ display: block;
+ margin-top: 5px;
+ width: 100%;
+}
+
+#content #schema .checkbox
+{
+ margin-bottom: 0;
+ width: auto;
+}
+
+#content #schema .chosen-container {
+ margin-left: 6px;
+ width: 100%;
+}
+#content #schema .chosen-drop input,
+#content #schema .chosen-results {
+ width: 100% !important;
+}
+
+#content #schema button span
+{
+ background-image: url( ../../img/ico/cross.png );
+}
+#content #schema button.submit span
+{
+ background-image: url( ../../img/ico/tick.png );
+}
+
+#content #schema .error
+{
+ background-image: url( ../../img/ico/cross-button.png );
+ background-position: 22% 1px;
+ color: #c00;
+ font-weight: bold;
+ margin-bottom: 10px;
+}
+
+#content #schema #actions .error span
+{
+ float: right;
+ width: 71%;
+ padding-left: 3px;
+ padding-right: 3px;
+}
+
+#content #schema .delete-field button span {
+ background-image: url( ../../img/ico/cross.png );
+}
+
+#content #schema span.rem {
+ background-image: url( ../../img/ico/cross.png );
+ background-position: 100% 50%;
+ cursor: pointer;
+ padding-right: 21px;
+ right:10px;
+ float:right;
+}
+
+#content #schema .copyfield .updatable a {
+ float:left;
+ width:80%;
+}
+
+#content #schema dd.similarity.ng-binding::after {
+ content: attr(data-tip) ;
+
+ font-size: 12px;
+ position: relative;
+ white-space: nowrap;
+ bottom: 9999px;
+ left: 0;
+ background: lightyellow;
+ color: black;
+ padding: 4px 7px;
+ line-height: 24px;
+ height: 24px;
+ border: 1px solid darkgray;
+ opacity: 0;
+ transition:opacity 0.4s ease-out;
+}
+
+#content #schema dd.similarity.ng-binding:hover::after {
+ opacity: 90;
+ bottom: -20px;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/segments.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/segments.css
new file mode 100755
index 0000000000..05f5f7bbd1
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/segments.css
@@ -0,0 +1,172 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #segments .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #segments .reload
+{
+ background-image: url( ../../img/ico/arrow-circle.png );
+ background-position: 50% 50%;
+ display: block;
+ height: 30px;
+ position: absolute;
+ right: 10px;
+ top: 10px;
+ width: 30px;
+}
+
+#content #segments .reload.loader
+{
+ padding-left: 0;
+}
+
+#content #segments .reload span
+{
+ display: none;
+}
+
+#content #segments #result
+{
+ width: 77%;
+}
+
+#content #segments #result #response
+{
+ margin-left: 25px;
+}
+
+#content #segments .segments-holder ul {
+ margin-left: 25px;
+}
+#content #segments .segments-holder li {
+ margin-bottom: 2px;
+ position: relative;
+ width: 100%;
+}
+
+#content #segments .segments-holder li .tooltip {
+ display: none;
+ background: #f0f0f0;
+ position: absolute;
+ z-index: 1000;
+ width:220px;
+ height:120px;
+ margin-left: 100%;
+ opacity: .8;
+ padding: 5px;
+ border: 1px solid;
+ border-radius: 5px;
+}
+
+#content #segments .segments-holder li .tooltip .label {
+ float: left;
+ width: 20%;
+ opacity: 1;
+}
+
+#content #segments .segments-holder li:hover .tooltip {
+ display:block;
+}
+
+#content #segments .segments-holder li dl,
+#content #segments .segments-holder li dt {
+ padding-bottom: 1px;
+ padding-top: 1px;
+}
+#content #segments .segments-holder li dl {
+ min-width: 1px;
+}
+#content #segments .segments-holder li dt {
+ color: #4D4D4D;
+ left: -45px;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+}
+#content #segments .segments-holder li dt div {
+ display: block;
+ padding-right: 4px;
+ text-align: right;
+}
+#content #segments .segments-holder li dd {
+ clear: left;
+ float: left;
+ margin-left: 2px;
+ white-space: nowrap;
+ width: 100%;
+}
+
+#content #segments .segments-holder li dd div.deleted {
+ background-color: #808080;
+ padding-left: 5px;
+}
+
+#content #segments .segments-holder li dd div.live {
+ background-color: #DDDDDD;
+ float: left;
+}
+
+#content #segments .segments-holder li dd div.start {
+ float: left;
+ width: 20%;
+}
+
+#content #segments .segments-holder li dd div.end {
+ text-align: right;
+}
+
+.merge-candidate {
+ background-color: #FFC9F9 !important;
+}
+
+#content #segments .segments-holder li dd div.w5 {
+ width: 20%;
+ float: left;
+}
+
+#content #segments #auto-refresh {
+ margin-top: 4px;
+ background-position: 50% 50%;
+ display: block;
+ height: 30px;
+ position: absolute;
+ right: 50px;
+ top: 10px;
+}
+
+#content #segments #auto-refresh a {
+ background-image: url( ../../img/ico/ui-check-box-uncheck.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ display: block;
+ padding-left: 21px;
+}
+
+#content #segments #auto-refresh a.on,
+#content #segments #auto-refresh a:hover {
+ color: #333;
+}
+
+#content #segments #auto-refresh a.on {
+ background-image: url( ../../img/ico/ui-check-box.png );
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/stream.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/stream.css
new file mode 100755
index 0000000000..0ebb592433
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/stream.css
@@ -0,0 +1,233 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #stream
+{
+}
+
+#content #stream #form
+{
+ float: top;
+}
+
+#content #stream #form label
+{
+ cursor: pointer;
+ display: inline;
+ margin-top: 5px;
+}
+
+#content #stream #form input,
+#content #stream #form select,
+#content #stream #form textarea
+{
+ margin-bottom: 2px;
+ width: 100%;
+}
+
+#content #stream #form textarea
+{
+ height: 125px;
+}
+
+#content #stream #form #start
+{
+ float: left;
+ width: 45%;
+}
+
+#content #stream #form #rows
+{
+ float: right;
+ width: 45%;
+}
+
+#content #stream #form input[type=checkbox]
+{
+ margin-bottom: 0;
+ margin-left: 5px;
+ margin-right: 0px;
+ width: 10px;
+ height: 10px;
+ display: inline;
+}
+
+#content #stream #form fieldset
+{
+ border: 1px solid #fff;
+ border-top: 1px solid #c0c0c0;
+ margin-bottom: 5px;
+}
+
+#content #stream #form fieldset.common
+{
+ margin-top: 10px;
+}
+
+#content #stream #form fieldset legend
+{
+ display: block;
+ margin-left: 10px;
+ padding: 0px 5px;
+}
+
+#content #stream #form fieldset legend label
+{
+ margin-top: 0;
+}
+
+#content #stream #form button
+{
+ margin-right: 10px;
+}
+
+#content #stream #form fieldset .fieldset
+{
+ border-bottom: 1px solid #f0f0f0;
+ margin-bottom: 5px;
+ padding-bottom: 10px;
+}
+
+#content #stream #result
+{
+ float: bottom;
+}
+
+#content #stream #result #response
+{
+}
+
+/************************/
+
+#content #stream #result #explanation
+{
+ border-top: 1px solid #f0f0f0;
+ border-bottom: 1px solid #f0f0f0;
+ border-left: 1px solid #f0f0f0;
+ border-right: 1px solid #f0f0f0;
+}
+
+#content #stream #result #explanation .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #stream #result #explanation #error
+{
+ background-color: #f00;
+ background-image: url( ../../img/ico/construction.png );
+ background-position: 10px 12px;
+ color: #fff;
+ font-weight: bold;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+}
+
+#content #stream #result #explanation #error .msg
+{
+ font-style: italic;
+ font-weight: normal;
+ margin-top: 10px;
+}
+
+#content #stream #result #explanation .content
+{
+ padding-left: 0;
+ padding-right: 0;
+}
+
+#content #stream #result #explanation .content.show
+{
+ background-image: url( ../../img/div.gif );
+ background-repeat: repeat-y;
+ background-position: 31% 0;
+}
+
+#content #stream #result #explanation #legend
+{
+ border: 1px solid #f0f0f0;
+ padding: 10px;
+ /*position: absolute;
+ right: 0;
+ bottom: 0;*/
+}
+
+#content #stream #result #explanation #legend li
+{
+ padding-left: 15px;
+ position: relative;
+ -webkit-box-sizing: border-box;
+}
+
+#content #stream #result #explanation #legend li svg
+{
+ position: absolute;
+ left: 0;
+ top: 2px;
+}
+
+#content #stream #result #explanation #explanation-content
+{
+ min-height: 50px;
+ width: 100%
+}
+
+#content #stream #result #explanation #explanation-content .node circle
+{
+ color: #c48f00;
+ stroke: #c48f00;
+ fill: #c48f00;
+}
+
+#content #stream #result #explanation #explanation-content .link
+{
+ fill: none;
+ stroke: #e0e0e0;
+ stroke-width: 1.5px;
+}
+
+#content #stream #result #explanation #legend .datastore circle,
+#content #stream #result #explanation #explanation-content .node.datastore circle
+{
+ stroke: #3800c4;
+ fill: #3800c4;
+}
+
+#content #stream #result #explanation #legend .stream-source circle,
+#content #stream #result #explanation #explanation-content .node.stream-source circle
+{
+ stroke: #21a9ec;
+ fill: #21a9ec;
+}
+
+#content #stream #result #explanation #legend .stream-decorator circle,
+#content #stream #result #explanation #explanation-content .node.stream-decorator circle
+{
+ stroke: #cb21ec;
+ fill: #cb21ec;
+}
+
+#content #stream #result #explanation #legend .graph-source circle,
+#content #stream #result #explanation #explanation-content .node.graph-source circle
+{
+ stroke: #21eca9;
+ fill: #21eca9;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/suggestions.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/suggestions.css
new file mode 100755
index 0000000000..6d9fa65997
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/suggestions.css
@@ -0,0 +1,64 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+#cluster-suggestions
+.s-container{
+ text-align:center;
+}
+#cluster-suggestions
+.s-box1{
+ background-image: url( ../../img/ico/run.png );
+ background-color: transparent;
+ background-repeat: no-repeat;
+ border: none;
+ cursor: pointer;
+ vertical-align: middle;
+ display:inline-block;
+ width:20px;
+}
+#cluster-suggestions
+.s-box2{
+ display:inline-block;
+}
+#cluster-suggestions
+.s-box3{
+ display:inline-block;
+}
+#cluster-suggestions
+.s-box4{
+ display:inline-block;
+}
+#s-table {
+ border-collapse: collapse;
+ width: 60%;
+}
+
+#s-table td, #customers th {
+ border: 1px solid #ddd;
+ padding: 8px;
+}
+
+#cluster-suggestions #s-table tr:nth-child(even){background-color: #f2f2f2;}
+
+#cluster-suggestions #s-table th {
+ padding-top: 12px;
+ padding-bottom: 12px;
+ text-align: left;
+ background-color: #4CAF50;
+ color: white;
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/threads.css b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/threads.css
new file mode 100755
index 0000000000..a457c86797
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/css/angular/threads.css
@@ -0,0 +1,160 @@
+/*
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+#content #threads .loader
+{
+ background-position: 0 50%;
+ padding-left: 21px;
+}
+
+#content #threads #thread-dump table
+{
+ border-collapse: collapse;
+ width: 100%;
+}
+
+#content #threads #thread-dump table .spacer,
+#content #threads #thread-dump tbody .state
+{
+ background-color: #fff;
+}
+
+#content #threads #thread-dump table th,
+#content #threads #thread-dump table td
+{
+ padding: 5px 3px;
+ vertical-align: top;
+}
+
+#content #threads #thread-dump thead th
+{
+ background-color: #c8c8c8;
+ font-weight: bold;
+ text-align: left;
+}
+
+#content #threads #thread-dump thead th.name
+{
+ width: 85%;
+}
+
+#content #threads #thread-dump thead th.time
+{
+ text-align: right;
+ width: 15%;
+}
+
+#content #threads #thread-dump tbody .odd
+{
+ background-color: #f0f0f0;
+}
+
+#content #threads #thread-dump tbody .RUNNABLE a
+{
+ background-image: url( ../../img/ico/tick-circle.png );
+}
+
+#content #threads #thread-dump tbody .WAITING a,
+#content #threads #thread-dump tbody .TIMED_WAITING a
+{
+ background-image: url( ../../img/ico/hourglass.png );
+}
+
+#content #threads #thread-dump tbody .WAITING.lock a,
+#content #threads #thread-dump tbody .TIMED_WAITING.lock a
+{
+ background-image: url( ../../img/ico/hourglass--exclamation.png );
+}
+
+#content #threads #thread-dump tbody .name a
+{
+ background-position: 0 50%;
+ cursor: auto;
+ display: block;
+ padding-left: 21px;
+}
+
+#content #threads #thread-dump tbody .stacktrace .name a
+{
+ cursor: pointer;
+}
+
+#content #threads #thread-dump tbody .stacktrace .name a span
+{
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ background-position: 100% 50%;
+ padding-right: 21px;
+}
+
+#content #threads #thread-dump tbody .stacktrace.open .name a span
+{
+ background-image: url( ../../img/ico/chevron-small.png );
+}
+
+#content #threads #thread-dump tbody .name p
+{
+ background-image: url( ../../img/ico/arrow-000-small.png );
+ background-position: 0 50%;
+ color: #4D4D4D;
+ font-size: 11px;
+ margin-left: 21px;
+ padding-left: 21px;
+}
+
+#content #threads #thread-dump tbody .name div
+{
+ border-top: 1px solid #c0c0c0;
+ margin-left: 21px;
+ margin-top: 5px;
+ padding-top: 5px;
+}
+
+#content #threads #thread-dump tbody .open .name div
+{
+ display: block;
+}
+
+#content #threads #thread-dump tbody .name ul
+{
+ list-style-type: disc;
+ margin-left: 0.7em;
+ padding-left: 0.7em;
+}
+
+#content #threads #thread-dump tbody .time
+{
+ text-align: right;
+}
+
+#content #threads .controls
+{
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+#content #threads .controls a
+{
+ background-image: url( ../../img/ico/chevron-small-expand.png );
+ padding-left: 21px;
+}
+
+#content #threads.expanded .controls a
+{
+ background-image: url( ../../img/ico/chevron-small.png );
+}
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/favicon.ico b/KeywordSearch/solr/server/solr-webapp/webapp/favicon.ico
new file mode 100755
index 0000000000..e93104ccff
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/favicon.ico differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/chosen-sprite-2x.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/chosen-sprite-2x.png
new file mode 100755
index 0000000000..6b50545202
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/chosen-sprite-2x.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/chosen-sprite.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/chosen-sprite.png
new file mode 100755
index 0000000000..113dc9885a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/chosen-sprite.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/div.gif b/KeywordSearch/solr/server/solr-webapp/webapp/img/div.gif
new file mode 100755
index 0000000000..963c9e97bd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/div.gif differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/favicon.ico b/KeywordSearch/solr/server/solr-webapp/webapp/img/favicon.ico
new file mode 100755
index 0000000000..e93104ccff
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/favicon.ico differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/7z.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/7z.png
new file mode 100755
index 0000000000..52f7d5d720
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/7z.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/README b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/README
new file mode 100755
index 0000000000..f7a8560715
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/README
@@ -0,0 +1,27 @@
+http://www.splitbrain.org/projects/file_icons
+
+Released to the Public Domain
+Free to use. Provided as is. No warranties.
+
+Note: The big majority of icons where created by the creators listed
+ below. Only a few ones where found on the net. They were too
+ widespread to determine the original author and thus were
+ considered public domain.
+ If you are the author of one of those icons just send a short
+ mail to either be included in the list below or have the icon
+ removed from the package.
+
+Creators:
+
+ Andreas Gohr
+ Michael Klier
+ Andreas Barton
+ Hubert Chathi
+ Johan Koehne
+ Rudi von Staden
+ Daniel Darvish
+ Andy Pascall
+ Seth
+ David Carella
+ Tom N. Harris
+ Brandon Carmon Colvin
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ai.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ai.png
new file mode 100755
index 0000000000..a999762c89
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ai.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/aiff.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/aiff.png
new file mode 100755
index 0000000000..82d523fdb1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/aiff.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/asc.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/asc.png
new file mode 100755
index 0000000000..d9fa4a8aae
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/asc.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/audio.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/audio.png
new file mode 100755
index 0000000000..98883256d6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/audio.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/bin.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/bin.png
new file mode 100755
index 0000000000..fbd174e2d5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/bin.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/bz2.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/bz2.png
new file mode 100755
index 0000000000..d48cae0384
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/bz2.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/c.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/c.png
new file mode 100755
index 0000000000..efe18f4392
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/c.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cfc.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cfc.png
new file mode 100755
index 0000000000..09c149d642
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cfc.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cfm.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cfm.png
new file mode 100755
index 0000000000..d755f286f1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cfm.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/chm.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/chm.png
new file mode 100755
index 0000000000..53d48f3b51
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/chm.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/class.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/class.png
new file mode 100755
index 0000000000..a39f70c161
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/class.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/conf.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/conf.png
new file mode 100755
index 0000000000..ddffe6fd1a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/conf.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cpp.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cpp.png
new file mode 100755
index 0000000000..79464401bd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cpp.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cs.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cs.png
new file mode 100755
index 0000000000..d5db29ba5d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/cs.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/css.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/css.png
new file mode 100755
index 0000000000..04012041c1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/css.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/csv.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/csv.png
new file mode 100755
index 0000000000..3a8835360e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/csv.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/deb.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/deb.png
new file mode 100755
index 0000000000..9229d87838
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/deb.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/divx.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/divx.png
new file mode 100755
index 0000000000..98dab8f808
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/divx.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/doc.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/doc.png
new file mode 100755
index 0000000000..932567f8a9
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/doc.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/dot.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/dot.png
new file mode 100755
index 0000000000..9f2da1add1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/dot.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/eml.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/eml.png
new file mode 100755
index 0000000000..02828e1738
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/eml.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/enc.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/enc.png
new file mode 100755
index 0000000000..cb2d7d47eb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/enc.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/file.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/file.png
new file mode 100755
index 0000000000..24d5f328cc
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/file.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/gif.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/gif.png
new file mode 100755
index 0000000000..b4c07a9120
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/gif.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/gz.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/gz.png
new file mode 100755
index 0000000000..2426bd169c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/gz.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/hlp.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/hlp.png
new file mode 100755
index 0000000000..4417d8e2cb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/hlp.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/htm.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/htm.png
new file mode 100755
index 0000000000..1a6812185b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/htm.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/html.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/html.png
new file mode 100755
index 0000000000..672cbce420
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/html.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/image.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/image.png
new file mode 100755
index 0000000000..f83e2898d5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/image.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/iso.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/iso.png
new file mode 100755
index 0000000000..1b2ff19ca7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/iso.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jar.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jar.png
new file mode 100755
index 0000000000..4db70a2c72
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jar.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/java.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/java.png
new file mode 100755
index 0000000000..7489b97213
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/java.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jpeg.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jpeg.png
new file mode 100755
index 0000000000..aa4cc23a5b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jpeg.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jpg.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jpg.png
new file mode 100755
index 0000000000..1fb6cc1fbf
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/jpg.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/js.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/js.png
new file mode 100755
index 0000000000..7db4de7e98
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/js.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/lua.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/lua.png
new file mode 100755
index 0000000000..7c07d023f9
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/lua.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/m.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/m.png
new file mode 100755
index 0000000000..aa0cbae8b1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/m.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mm.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mm.png
new file mode 100755
index 0000000000..b737571c5e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mm.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mov.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mov.png
new file mode 100755
index 0000000000..7e7aa368f7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mov.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mp3.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mp3.png
new file mode 100755
index 0000000000..928705d7a5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mp3.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mpg.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mpg.png
new file mode 100755
index 0000000000..9a3f8ea51e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/mpg.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odc.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odc.png
new file mode 100755
index 0000000000..47f65c84d3
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odc.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odf.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odf.png
new file mode 100755
index 0000000000..a2fbc5195a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odf.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odg.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odg.png
new file mode 100755
index 0000000000..434f18262f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odg.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odi.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odi.png
new file mode 100755
index 0000000000..74f6303d3d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odi.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odp.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odp.png
new file mode 100755
index 0000000000..a5c77f845f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odp.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ods.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ods.png
new file mode 100755
index 0000000000..2ab1273f0d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ods.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odt.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odt.png
new file mode 100755
index 0000000000..b0c21fc1fd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/odt.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ogg.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ogg.png
new file mode 100755
index 0000000000..62cea6aaa4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ogg.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pdf.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pdf.png
new file mode 100755
index 0000000000..638066dea6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pdf.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pgp.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pgp.png
new file mode 100755
index 0000000000..e6b35f36ed
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pgp.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/php.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/php.png
new file mode 100755
index 0000000000..44c0fe0a08
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/php.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pl.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pl.png
new file mode 100755
index 0000000000..ad2324e359
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/pl.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/png.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/png.png
new file mode 100755
index 0000000000..f0b5b00eee
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/png.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ppt.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ppt.png
new file mode 100755
index 0000000000..adaefc6025
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ppt.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ps.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ps.png
new file mode 100755
index 0000000000..487c3cb7c2
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ps.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/py.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/py.png
new file mode 100755
index 0000000000..9e31edb553
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/py.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ram.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ram.png
new file mode 100755
index 0000000000..1a54d76543
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/ram.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rar.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rar.png
new file mode 100755
index 0000000000..a6af4d1cac
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rar.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rb.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rb.png
new file mode 100755
index 0000000000..30670165f9
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rb.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rm.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rm.png
new file mode 100755
index 0000000000..a2db68e32d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rm.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rpm.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rpm.png
new file mode 100755
index 0000000000..22212eafac
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rpm.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rtf.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rtf.png
new file mode 100755
index 0000000000..d8bada5fe1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/rtf.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sig.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sig.png
new file mode 100755
index 0000000000..3d8b19d2b3
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sig.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sql.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sql.png
new file mode 100755
index 0000000000..f60054a3af
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sql.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/swf.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/swf.png
new file mode 100755
index 0000000000..0729ed0203
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/swf.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxc.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxc.png
new file mode 100755
index 0000000000..419c183c1f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxc.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxd.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxd.png
new file mode 100755
index 0000000000..5801bb23a6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxd.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxi.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxi.png
new file mode 100755
index 0000000000..2a94290d70
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxi.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxw.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxw.png
new file mode 100755
index 0000000000..6da97beb35
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/sxw.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tar.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tar.png
new file mode 100755
index 0000000000..5a2f717fc5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tar.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tex.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tex.png
new file mode 100755
index 0000000000..e46a5166f9
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tex.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tgz.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tgz.png
new file mode 100755
index 0000000000..141acf5647
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/tgz.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/txt.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/txt.png
new file mode 100755
index 0000000000..da20009c6e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/txt.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/vcf.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/vcf.png
new file mode 100755
index 0000000000..195ab38bc7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/vcf.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/video.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/video.png
new file mode 100755
index 0000000000..b89fc52995
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/video.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/vsd.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/vsd.png
new file mode 100755
index 0000000000..d14b81d989
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/vsd.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wav.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wav.png
new file mode 100755
index 0000000000..79e80760e2
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wav.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wma.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wma.png
new file mode 100755
index 0000000000..6854de7722
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wma.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wmv.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wmv.png
new file mode 100755
index 0000000000..b26f45d5f3
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/wmv.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xls.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xls.png
new file mode 100755
index 0000000000..e8cd58dc0f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xls.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xml.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xml.png
new file mode 100755
index 0000000000..eb46323979
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xml.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xpi.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xpi.png
new file mode 100755
index 0000000000..5e537e2375
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xpi.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xvid.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xvid.png
new file mode 100755
index 0000000000..d8429dc1ae
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/xvid.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/zip.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/zip.png
new file mode 100755
index 0000000000..999ffbe807
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/filetypes/zip.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-000-small.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-000-small.png
new file mode 100755
index 0000000000..cfc2e2493f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-000-small.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-circle.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-circle.png
new file mode 100755
index 0000000000..dda7132750
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-circle.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-switch.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-switch.png
new file mode 100755
index 0000000000..ab3dd3021d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/arrow-switch.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/asterisk.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/asterisk.png
new file mode 100755
index 0000000000..c2fbed5a74
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/asterisk.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/battery.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/battery.png
new file mode 100755
index 0000000000..7a825b0257
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/battery.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/block-small.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/block-small.png
new file mode 100755
index 0000000000..7cc52813cd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/block-small.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/block.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/block.png
new file mode 100755
index 0000000000..ed7ec0e972
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/block.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/book-open-text.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/book-open-text.png
new file mode 100755
index 0000000000..069fae7c95
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/book-open-text.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/box.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/box.png
new file mode 100755
index 0000000000..3ec0ceb131
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/box.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/bug.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/bug.png
new file mode 100755
index 0000000000..242d5391c1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/bug.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chart.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chart.png
new file mode 100755
index 0000000000..d3cb71d5c5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chart.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chevron-small-expand.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chevron-small-expand.png
new file mode 100755
index 0000000000..06a8eaca13
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chevron-small-expand.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chevron-small.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chevron-small.png
new file mode 100755
index 0000000000..b54fd1c7c2
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/chevron-small.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-list.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-list.png
new file mode 100755
index 0000000000..e98c567563
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-list.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-paste-document-text.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-paste-document-text.png
new file mode 100755
index 0000000000..08647f1bee
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-paste-document-text.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-paste.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-paste.png
new file mode 100755
index 0000000000..0cf8887292
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clipboard-paste.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clock-select-remain.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clock-select-remain.png
new file mode 100755
index 0000000000..8c665b812e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clock-select-remain.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clock-select.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clock-select.png
new file mode 100755
index 0000000000..8c567916c8
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/clock-select.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/construction.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/construction.png
new file mode 100755
index 0000000000..8347aa896f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/construction.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-0.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-0.png
new file mode 100755
index 0000000000..04fef989e7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-0.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-1.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-1.png
new file mode 100755
index 0000000000..830879b618
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-1.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-button.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-button.png
new file mode 100755
index 0000000000..933272b493
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross-button.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross.png
new file mode 100755
index 0000000000..6b9fa6dd36
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/cross.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/dashboard.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/dashboard.png
new file mode 100755
index 0000000000..ba03262f0c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/dashboard.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/database--plus.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/database--plus.png
new file mode 100755
index 0000000000..2558a7d6a6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/database--plus.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/database.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/database.png
new file mode 100755
index 0000000000..d588f422f7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/database.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/databases.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/databases.png
new file mode 100755
index 0000000000..11dcab4b1b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/databases.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/disk-black.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/disk-black.png
new file mode 100755
index 0000000000..61784784f0
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/disk-black.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-convert.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-convert.png
new file mode 100755
index 0000000000..1ecdafb99a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-convert.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-import.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-import.png
new file mode 100755
index 0000000000..5fae085f85
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-import.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-list.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-list.png
new file mode 100755
index 0000000000..2b4dde893e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-list.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-text.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-text.png
new file mode 100755
index 0000000000..ed841a02a7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/document-text.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/documents-stack.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/documents-stack.png
new file mode 100755
index 0000000000..a397f60aaa
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/documents-stack.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/download-cloud.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/download-cloud.png
new file mode 100755
index 0000000000..ba0f492fa4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/download-cloud.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/drive-upload.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/drive-upload.png
new file mode 100755
index 0000000000..93589e4da3
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/drive-upload.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/exclamation-button.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/exclamation-button.png
new file mode 100755
index 0000000000..e792fb01d5
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/exclamation-button.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/eye.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/eye.png
new file mode 100755
index 0000000000..2aead17e09
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/eye.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder-export.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder-export.png
new file mode 100755
index 0000000000..86e0cd294c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder-export.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder-tree.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder-tree.png
new file mode 100755
index 0000000000..24218b6dbd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder-tree.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder.png
new file mode 100755
index 0000000000..ada85c48b8
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/folder.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/funnel-small.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/funnel-small.png
new file mode 100755
index 0000000000..96e9e28f25
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/funnel-small.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/funnel.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/funnel.png
new file mode 100755
index 0000000000..1f69604528
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/funnel.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/gear.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/gear.png
new file mode 100755
index 0000000000..efc599dccd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/gear.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/globe-network.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/globe-network.png
new file mode 100755
index 0000000000..ec27fad42b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/globe-network.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/globe.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/globe.png
new file mode 100755
index 0000000000..48e5b6b30c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/globe.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hammer-screwdriver.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hammer-screwdriver.png
new file mode 100755
index 0000000000..985d44c5e7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hammer-screwdriver.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hammer.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hammer.png
new file mode 100755
index 0000000000..cf0ef85a78
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hammer.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hand.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hand.png
new file mode 100755
index 0000000000..7b47be2dc9
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hand.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/highlighter-text.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/highlighter-text.png
new file mode 100755
index 0000000000..719c537dbb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/highlighter-text.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/home.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/home.png
new file mode 100755
index 0000000000..622a2b736d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/home.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hourglass--exclamation.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hourglass--exclamation.png
new file mode 100755
index 0000000000..67436681a1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hourglass--exclamation.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hourglass.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hourglass.png
new file mode 100755
index 0000000000..127c5d6156
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/hourglass.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/idea.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/idea.png
new file mode 100755
index 0000000000..8b3abbd5e9
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/idea.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/inbox-document-text.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/inbox-document-text.png
new file mode 100755
index 0000000000..4b479cfef6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/inbox-document-text.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-button.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-button.png
new file mode 100755
index 0000000000..4ecaf370bd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-button.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-small.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-small.png
new file mode 100755
index 0000000000..6db2d56e97
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-small.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-white.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-white.png
new file mode 100755
index 0000000000..bd4f552a8b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information-white.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information.png
new file mode 100755
index 0000000000..fa9a60b5ad
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/information.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/jar.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/jar.png
new file mode 100755
index 0000000000..8711832acc
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/jar.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/magnifier.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/magnifier.png
new file mode 100755
index 0000000000..7a5ae62e32
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/magnifier.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/mail.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/mail.png
new file mode 100755
index 0000000000..e708416dac
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/mail.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/memory.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/memory.png
new file mode 100755
index 0000000000..4c71a247d6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/memory.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/minus-button.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/minus-button.png
new file mode 100755
index 0000000000..6dc019a60b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/minus-button.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/molecule.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/molecule.png
new file mode 100755
index 0000000000..c4eac4ef4b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/molecule.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-cloud.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-cloud.png
new file mode 100755
index 0000000000..0527a92ba1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-cloud.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-away.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-away.png
new file mode 100755
index 0000000000..0defbb40d9
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-away.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-busy.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-busy.png
new file mode 100755
index 0000000000..ba2c65473c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-busy.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-offline.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-offline.png
new file mode 100755
index 0000000000..507ff05959
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status-offline.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status.png
new file mode 100755
index 0000000000..12ccc6baff
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network-status.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network.png
new file mode 100755
index 0000000000..8224771b0d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/network.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-design.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-design.png
new file mode 100755
index 0000000000..fb2d4066c7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-design.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-master.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-master.png
new file mode 100755
index 0000000000..c40fcc3ee4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-master.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-select.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-select.png
new file mode 100755
index 0000000000..d2aba04ccb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-select.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-slave.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-slave.png
new file mode 100755
index 0000000000..78a41cd127
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node-slave.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node.png
new file mode 100755
index 0000000000..88f1a2bbf1
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/node.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/pencil-small.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/pencil-small.png
new file mode 100755
index 0000000000..3d81c2fb13
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/pencil-small.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/pencil.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/pencil.png
new file mode 100755
index 0000000000..3ef2fa63e2
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/pencil.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/plus-button.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/plus-button.png
new file mode 100755
index 0000000000..10d1f60031
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/plus-button.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/processor.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/processor.png
new file mode 100755
index 0000000000..37e9794222
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/processor.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/prohibition.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/prohibition.png
new file mode 100755
index 0000000000..18f151071a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/prohibition.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/property.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/property.png
new file mode 100755
index 0000000000..b0e549e453
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/property.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question-small-white.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question-small-white.png
new file mode 100755
index 0000000000..132d3f5bad
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question-small-white.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question-white.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question-white.png
new file mode 100755
index 0000000000..f806468719
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question-white.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question.png
new file mode 100755
index 0000000000..30a47032a4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/question.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/receipt-invoice.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/receipt-invoice.png
new file mode 100755
index 0000000000..fed614079f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/receipt-invoice.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/receipt.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/receipt.png
new file mode 100755
index 0000000000..1548b0ac60
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/receipt.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/run.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/run.png
new file mode 100755
index 0000000000..dc35fe3cb2
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/run.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/script-code.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/script-code.png
new file mode 100755
index 0000000000..d398622dfd
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/script-code.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/server-cast.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/server-cast.png
new file mode 100755
index 0000000000..9213866525
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/server-cast.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/server.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/server.png
new file mode 100755
index 0000000000..ee0c771797
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/server.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/sitemap.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/sitemap.png
new file mode 100755
index 0000000000..298343eeab
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/sitemap.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/slash.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/slash.png
new file mode 100755
index 0000000000..7af3a5189d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/slash.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-away.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-away.png
new file mode 100755
index 0000000000..c7be0abbe4
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-away.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-busy.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-busy.png
new file mode 100755
index 0000000000..a9d5f4db20
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-busy.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-offline.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-offline.png
new file mode 100755
index 0000000000..f148af4985
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status-offline.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status.png
new file mode 100755
index 0000000000..680bb8a6a6
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/status.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/system-monitor--exclamation.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/system-monitor--exclamation.png
new file mode 100755
index 0000000000..c6f6a5f646
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/system-monitor--exclamation.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/system-monitor.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/system-monitor.png
new file mode 100755
index 0000000000..a139103e11
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/system-monitor.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/table.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/table.png
new file mode 100755
index 0000000000..b0cd69fc5d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/table.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/terminal.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/terminal.png
new file mode 100755
index 0000000000..c18df24f94
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/terminal.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick-circle.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick-circle.png
new file mode 100755
index 0000000000..210b1a6c3c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick-circle.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick-red.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick-red.png
new file mode 100755
index 0000000000..8ec99b4a69
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick-red.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick.png
new file mode 100755
index 0000000000..2414885b85
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/tick.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toggle-small-expand.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toggle-small-expand.png
new file mode 100755
index 0000000000..79c5ff7e80
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toggle-small-expand.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toggle-small.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toggle-small.png
new file mode 100755
index 0000000000..f783a6f2cb
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toggle-small.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toolbox.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toolbox.png
new file mode 100755
index 0000000000..b581d7794d
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/toolbox.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-accordion.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-accordion.png
new file mode 100755
index 0000000000..a9f1448e29
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-accordion.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-address-bar.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-address-bar.png
new file mode 100755
index 0000000000..1a96ac435e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-address-bar.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-check-box-uncheck.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-check-box-uncheck.png
new file mode 100755
index 0000000000..ba447358cc
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-check-box-uncheck.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-check-box.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-check-box.png
new file mode 100755
index 0000000000..07f3522a9c
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-check-box.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-radio-button-uncheck.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-radio-button-uncheck.png
new file mode 100755
index 0000000000..ec7102b6ef
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-radio-button-uncheck.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-radio-button.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-radio-button.png
new file mode 100755
index 0000000000..f83a25496e
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-radio-button.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-text-field-select.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-text-field-select.png
new file mode 100755
index 0000000000..3cfe301ac7
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/ui-text-field-select.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/users.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/users.png
new file mode 100755
index 0000000000..a6aae0404b
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/users.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/wooden-box.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/wooden-box.png
new file mode 100755
index 0000000000..f64d761057
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/wooden-box.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/zone.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/zone.png
new file mode 100755
index 0000000000..80fc7be9e0
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/ico/zone.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/loader-light.gif b/KeywordSearch/solr/server/solr-webapp/webapp/img/loader-light.gif
new file mode 100755
index 0000000000..f578ca586f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/loader-light.gif differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/loader.gif b/KeywordSearch/solr/server/solr-webapp/webapp/img/loader.gif
new file mode 100755
index 0000000000..085ccaecaf
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/loader.gif differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/lucene-ico.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/lucene-ico.png
new file mode 100755
index 0000000000..43327dd5ac
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/lucene-ico.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/solr-ico.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/solr-ico.png
new file mode 100755
index 0000000000..91c35d846f
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/solr-ico.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/solr.svg b/KeywordSearch/solr/server/solr-webapp/webapp/img/solr.svg
new file mode 100755
index 0000000000..cb4ae64f81
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/img/solr.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/img/tree.png b/KeywordSearch/solr/server/solr-webapp/webapp/img/tree.png
new file mode 100755
index 0000000000..61b6b3ee1a
Binary files /dev/null and b/KeywordSearch/solr/server/solr-webapp/webapp/img/tree.png differ
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/index.html b/KeywordSearch/solr/server/solr-webapp/webapp/index.html
new file mode 100755
index 0000000000..f1e6a2e8fe
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/index.html
@@ -0,0 +1,253 @@
+
+
+
+
+
+ Solr Admin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ it('should linkify the snippet with urls', function() {
+ expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+ toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
+ 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+ expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
+ });
+
+ it('should not linkify snippet without the linky filter', function() {
+ expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
+ toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
+ 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+ expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
+ });
+
+ it('should update', function() {
+ element(by.model('snippet')).clear();
+ element(by.model('snippet')).sendKeys('new http://link.');
+ expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+ toBe('new http://link.');
+ expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
+ expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
+ .toBe('new http://link.');
+ });
+
+ it('should work with the target property', function() {
+ expect(element(by.id('linky-target')).
+ element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
+ toBe('http://angularjs.org/');
+ expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
+ });
+
+
+ */
+angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
+ var LINKY_URL_REGEXP =
+ /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"”’]/,
+ MAILTO_REGEXP = /^mailto:/;
+
+ return function(text, target) {
+ if (!text) return text;
+ var match;
+ var raw = text;
+ var html = [];
+ var url;
+ var i;
+ while ((match = raw.match(LINKY_URL_REGEXP))) {
+ // We can not end in these as they are sometimes found at the end of the sentence
+ url = match[0];
+ // if we did not match ftp/http/www/mailto then assume mailto
+ if (!match[2] && !match[4]) {
+ url = (match[3] ? 'http://' : 'mailto:') + url;
+ }
+ i = match.index;
+ addText(raw.substr(0, i));
+ addLink(url, match[0].replace(MAILTO_REGEXP, ''));
+ raw = raw.substring(i + match[0].length);
+ }
+ addText(raw);
+ return $sanitize(html.join(''));
+
+ function addText(text) {
+ if (!text) {
+ return;
+ }
+ html.push(sanitizeText(text));
+ }
+
+ function addLink(url, text) {
+ html.push('');
+ addText(text);
+ html.push('');
+ }
+ };
+}]);
+
+
+})(window, window.angular);
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-sanitize.min.js b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-sanitize.min.js
new file mode 100755
index 0000000000..e657c5b75e
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-sanitize.min.js
@@ -0,0 +1,39 @@
+/*
+The MIT License
+
+Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/*
+ AngularJS v1.3.8
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(n,h,p){'use strict';function E(a){var d=[];s(d,h.noop).chars(a);return d.join("")}function g(a){var d={};a=a.split(",");var c;for(c=0;c=c;e--)d.end&&d.end(f[e]);f.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,f=[],m=a,l;for(f.last=function(){return f[f.length-1]};a;){l="";k=!0;if(f.last()&&x[f.last()])a=a.replace(new RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");d.chars&&d.chars(r(b));return""}),e("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(d.comment&&d.comment(a.substring(4,
+b)),a=a.substring(b+3),k=!1);else if(y.test(a)){if(b=a.match(y))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(z))a=a.substring(b[0].length),b[0].replace(z,e),k=!1}else K.test(a)&&((b=a.match(A))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(A,c)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),d.chars&&d.chars(r(l)))}if(a==m)throw L("badparse",a);m=a}e()}function r(a){if(!a)return"";var d=M.exec(a);a=d[1];var c=d[3];if(d=d[2])q.innerHTML=
+d.replace(//g,">")}function s(a,d){var c=!1,e=h.bind(a,a.push);return{start:function(a,k,f){a=h.lowercase(a);!c&&x[a]&&(c=a);c||!0!==C[a]||(e("<"),e(a),h.forEach(k,function(c,f){var k=
+h.lowercase(f),g="img"===a&&"src"===k||"background"===k;!0!==P[k]||!0===D[k]&&!d(c,g)||(e(" "),e(f),e('="'),e(B(c)),e('"'))}),e(f?"/>":">"))},end:function(a){a=h.lowercase(a);c||!0!==C[a]||(e(""),e(a),e(">"));a==c&&(c=!1)},chars:function(a){c||e(B(a))}}}var L=h.$$minErr("$sanitize"),A=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,z=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^,
+J=/^<\//,H=/\x3c!--(.*?)--\x3e/g,y=/]*?)>/i,I=/"\u201d\u2019]/,c=/^mailto:/;return function(e,b){function k(a){a&&g.push(E(a))}
+function f(a,c){g.push("');k(c);g.push("")}if(!e)return e;for(var m,l=e,g=[],n,p;m=l.match(d);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),f(n,m[0].replace(c,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular);
+//# sourceMappingURL=angular-sanitize.min.js.map
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-utf8-base64.js b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-utf8-base64.js
new file mode 100755
index 0000000000..a3a735869f
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-utf8-base64.js
@@ -0,0 +1,217 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Andrey Bezyazychniy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+'use strict';
+
+angular.module('ab-base64',[]).constant('base64', (function() {
+
+ /*
+ * Encapsulation of Vassilis Petroulias's base64.js library for AngularJS
+ * Original notice included below
+ */
+
+ /*
+ Copyright Vassilis Petroulias [DRDigit]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+ var B64 = {
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
+ lookup: null,
+ ie: /MSIE /.test(navigator.userAgent),
+ ieo: /MSIE [67]/.test(navigator.userAgent),
+ encode: function (s) {
+ /* jshint bitwise:false */
+ var buffer = B64.toUtf8(s),
+ position = -1,
+ result,
+ len = buffer.length,
+ nan0, nan1, nan2, enc = [, , , ];
+
+ if (B64.ie) {
+ result = [];
+ while (++position < len) {
+ nan0 = buffer[position];
+ nan1 = buffer[++position];
+ enc[0] = nan0 >> 2;
+ enc[1] = ((nan0 & 3) << 4) | (nan1 >> 4);
+ if (isNaN(nan1))
+ enc[2] = enc[3] = 64;
+ else {
+ nan2 = buffer[++position];
+ enc[2] = ((nan1 & 15) << 2) | (nan2 >> 6);
+ enc[3] = (isNaN(nan2)) ? 64 : nan2 & 63;
+ }
+ result.push(B64.alphabet.charAt(enc[0]), B64.alphabet.charAt(enc[1]), B64.alphabet.charAt(enc[2]), B64.alphabet.charAt(enc[3]));
+ }
+ return result.join('');
+ } else {
+ result = '';
+ while (++position < len) {
+ nan0 = buffer[position];
+ nan1 = buffer[++position];
+ enc[0] = nan0 >> 2;
+ enc[1] = ((nan0 & 3) << 4) | (nan1 >> 4);
+ if (isNaN(nan1))
+ enc[2] = enc[3] = 64;
+ else {
+ nan2 = buffer[++position];
+ enc[2] = ((nan1 & 15) << 2) | (nan2 >> 6);
+ enc[3] = (isNaN(nan2)) ? 64 : nan2 & 63;
+ }
+ result += B64.alphabet[enc[0]] + B64.alphabet[enc[1]] + B64.alphabet[enc[2]] + B64.alphabet[enc[3]];
+ }
+ return result;
+ }
+ },
+ decode: function (s) {
+ /* jshint bitwise:false */
+ s = s.replace(/\s/g, '');
+ if (s.length % 4)
+ throw new Error('InvalidLengthError: decode failed: The string to be decoded is not the correct length for a base64 encoded string.');
+ if(/[^A-Za-z0-9+\/=\s]/g.test(s))
+ throw new Error('InvalidCharacterError: decode failed: The string contains characters invalid in a base64 encoded string.');
+
+ var buffer = B64.fromUtf8(s),
+ position = 0,
+ result,
+ len = buffer.length;
+
+ if (B64.ieo) {
+ result = [];
+ while (position < len) {
+ if (buffer[position] < 128)
+ result.push(String.fromCharCode(buffer[position++]));
+ else if (buffer[position] > 191 && buffer[position] < 224)
+ result.push(String.fromCharCode(((buffer[position++] & 31) << 6) | (buffer[position++] & 63)));
+ else
+ result.push(String.fromCharCode(((buffer[position++] & 15) << 12) | ((buffer[position++] & 63) << 6) | (buffer[position++] & 63)));
+ }
+ return result.join('');
+ } else {
+ result = '';
+ while (position < len) {
+ if (buffer[position] < 128)
+ result += String.fromCharCode(buffer[position++]);
+ else if (buffer[position] > 191 && buffer[position] < 224)
+ result += String.fromCharCode(((buffer[position++] & 31) << 6) | (buffer[position++] & 63));
+ else
+ result += String.fromCharCode(((buffer[position++] & 15) << 12) | ((buffer[position++] & 63) << 6) | (buffer[position++] & 63));
+ }
+ return result;
+ }
+ },
+ toUtf8: function (s) {
+ /* jshint bitwise:false */
+ var position = -1,
+ len = s.length,
+ chr, buffer = [];
+ if (/^[\x00-\x7f]*$/.test(s)) while (++position < len)
+ buffer.push(s.charCodeAt(position));
+ else while (++position < len) {
+ chr = s.charCodeAt(position);
+ if (chr < 128)
+ buffer.push(chr);
+ else if (chr < 2048)
+ buffer.push((chr >> 6) | 192, (chr & 63) | 128);
+ else
+ buffer.push((chr >> 12) | 224, ((chr >> 6) & 63) | 128, (chr & 63) | 128);
+ }
+ return buffer;
+ },
+ fromUtf8: function (s) {
+ /* jshint bitwise:false */
+ var position = -1,
+ len, buffer = [],
+ enc = [, , , ];
+ if (!B64.lookup) {
+ len = B64.alphabet.length;
+ B64.lookup = {};
+ while (++position < len)
+ B64.lookup[B64.alphabet.charAt(position)] = position;
+ position = -1;
+ }
+ len = s.length;
+ while (++position < len) {
+ enc[0] = B64.lookup[s.charAt(position)];
+ enc[1] = B64.lookup[s.charAt(++position)];
+ buffer.push((enc[0] << 2) | (enc[1] >> 4));
+ enc[2] = B64.lookup[s.charAt(++position)];
+ if (enc[2] === 64)
+ break;
+ buffer.push(((enc[1] & 15) << 4) | (enc[2] >> 2));
+ enc[3] = B64.lookup[s.charAt(++position)];
+ if (enc[3] === 64)
+ break;
+ buffer.push(((enc[2] & 3) << 6) | enc[3]);
+ }
+ return buffer;
+ }
+ };
+
+ var B64url = {
+ decode: function(input) {
+ // Replace non-url compatible chars with base64 standard chars
+ input = input
+ .replace(/-/g, '+')
+ .replace(/_/g, '/');
+
+ // Pad out with standard base64 required padding characters
+ var pad = input.length % 4;
+ if(pad) {
+ if(pad === 1) {
+ throw new Error('InvalidLengthError: Input base64url string is the wrong length to determine padding');
+ }
+ input += new Array(5-pad).join('=');
+ }
+
+ return B64.decode(input);
+ },
+
+ encode: function(input) {
+ var output = B64.encode(input);
+ return output
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_')
+ .split('=', 1)[0];
+ }
+ };
+
+ return {
+ decode: B64.decode,
+ encode: B64.encode,
+ urldecode: B64url.decode,
+ urlencode: B64url.encode,
+ };
+})());
+
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-utf8-base64.min.js b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-utf8-base64.min.js
new file mode 100755
index 0000000000..e1166c692f
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular-utf8-base64.min.js
@@ -0,0 +1,45 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Andrey Bezyazychniy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*
+ * Encapsulation of Vassilis Petroulias's base64.js library for AngularJS
+ * Original notice included below
+ */
+
+/*
+ Copyright Vassilis Petroulias [DRDigit]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+"use strict";angular.module("ab-base64",[]).constant("base64",function(){var a={alphabet:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",lookup:null,ie:/MSIE /.test(navigator.userAgent),ieo:/MSIE [67]/.test(navigator.userAgent),encode:function(b){var c,d,e,f,g=a.toUtf8(b),h=-1,i=g.length,j=[,,,];if(a.ie){for(c=[];++h>2,j[1]=(3&d)<<4|e>>4,isNaN(e)?j[2]=j[3]=64:(f=g[++h],j[2]=(15&e)<<2|f>>6,j[3]=isNaN(f)?64:63&f),c.push(a.alphabet.charAt(j[0]),a.alphabet.charAt(j[1]),a.alphabet.charAt(j[2]),a.alphabet.charAt(j[3]));return c.join("")}for(c="";++h>2,j[1]=(3&d)<<4|e>>4,isNaN(e)?j[2]=j[3]=64:(f=g[++h],j[2]=(15&e)<<2|f>>6,j[3]=isNaN(f)?64:63&f),c+=a.alphabet[j[0]]+a.alphabet[j[1]]+a.alphabet[j[2]]+a.alphabet[j[3]];return c},decode:function(b){if(b=b.replace(/\s/g,""),b.length%4)throw new Error("InvalidLengthError: decode failed: The string to be decoded is not the correct length for a base64 encoded string.");if(/[^A-Za-z0-9+\/=\s]/g.test(b))throw new Error("InvalidCharacterError: decode failed: The string contains characters invalid in a base64 encoded string.");var c,d=a.fromUtf8(b),e=0,f=d.length;if(a.ieo){for(c=[];f>e;)c.push(d[e]<128?String.fromCharCode(d[e++]):d[e]>191&&d[e]<224?String.fromCharCode((31&d[e++])<<6|63&d[e++]):String.fromCharCode((15&d[e++])<<12|(63&d[e++])<<6|63&d[e++]));return c.join("")}for(c="";f>e;)c+=String.fromCharCode(d[e]<128?d[e++]:d[e]>191&&d[e]<224?(31&d[e++])<<6|63&d[e++]:(15&d[e++])<<12|(63&d[e++])<<6|63&d[e++]);return c},toUtf8:function(a){var b,c=-1,d=a.length,e=[];if(/^[\x00-\x7f]*$/.test(a))for(;++cb?e.push(b):2048>b?e.push(b>>6|192,63&b|128):e.push(b>>12|224,b>>6&63|128,63&b|128);return e},fromUtf8:function(b){var c,d=-1,e=[],f=[,,,];if(!a.lookup){for(c=a.alphabet.length,a.lookup={};++d>4),f[2]=a.lookup[b.charAt(++d)],64!==f[2])&&(e.push((15&f[1])<<4|f[2]>>2),f[3]=a.lookup[b.charAt(++d)],64!==f[3]);)e.push((3&f[2])<<6|f[3]);return e}},b={decode:function(b){b=b.replace(/-/g,"+").replace(/_/g,"/");var c=b.length%4;if(c){if(1===c)throw new Error("InvalidLengthError: Input base64url string is the wrong length to determine padding");b+=new Array(5-c).join("=")}return a.decode(b)},encode:function(b){var c=a.encode(b);return c.replace(/\+/g,"-").replace(/\//g,"_").split("=",1)[0]}};return{decode:a.decode,encode:a.encode,urldecode:b.decode,urlencode:b.encode}}());
\ No newline at end of file
diff --git a/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular.js b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular.js
new file mode 100755
index 0000000000..aebeef1652
--- /dev/null
+++ b/KeywordSearch/solr/server/solr-webapp/webapp/libs/angular.js
@@ -0,0 +1,26093 @@
+/*
+The MIT License
+
+Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/**
+ * @license AngularJS v1.3.8
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, document, undefined) {'use strict';
+
+/**
+ * @description
+ *
+ * This object provides a utility for producing rich Error messages within
+ * Angular. It can be called as follows:
+ *
+ * var exampleMinErr = minErr('example');
+ * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
+ *
+ * The above creates an instance of minErr in the example namespace. The
+ * resulting error will have a namespaced error code of example.one. The
+ * resulting error will replace {0} with the value of foo, and {1} with the
+ * value of bar. The object is not restricted in the number of arguments it can
+ * take.
+ *
+ * If fewer arguments are specified than necessary for interpolation, the extra
+ * interpolation markers will be preserved in the final string.
+ *
+ * Since data will be parsed statically during a build step, some restrictions
+ * are applied with respect to how minErr instances are created and called.
+ * Instances should have names of the form namespaceMinErr for a minErr created
+ * using minErr('namespace') . Error codes, namespaces and template strings
+ * should all be static strings, not variables or general expressions.
+ *
+ * @param {string} module The namespace to use for the new minErr instance.
+ * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
+ * error from returned function, for cases when a particular type of error is useful.
+ * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
+ */
+
+function minErr(module, ErrorConstructor) {
+ ErrorConstructor = ErrorConstructor || Error;
+ return function() {
+ var code = arguments[0],
+ prefix = '[' + (module ? module + ':' : '') + code + '] ',
+ template = arguments[1],
+ templateArgs = arguments,
+
+ message, i;
+
+ message = prefix + template.replace(/\{\d+\}/g, function(match) {
+ var index = +match.slice(1, -1), arg;
+
+ if (index + 2 < templateArgs.length) {
+ return toDebugString(templateArgs[index + 2]);
+ }
+ return match;
+ });
+
+ message = message + '\nhttp://errors.angularjs.org/1.3.8/' +
+ (module ? module + '/' : '') + code;
+ for (i = 2; i < arguments.length; i++) {
+ message = message + (i == 2 ? '?' : '&') + 'p' + (i - 2) + '=' +
+ encodeURIComponent(toDebugString(arguments[i]));
+ }
+ return new ErrorConstructor(message);
+ };
+}
+
+/* We need to tell jshint what variables are being exported */
+/* global angular: true,
+ msie: true,
+ jqLite: true,
+ jQuery: true,
+ slice: true,
+ splice: true,
+ push: true,
+ toString: true,
+ ngMinErr: true,
+ angularModule: true,
+ uid: true,
+ REGEX_STRING_REGEXP: true,
+ VALIDITY_STATE_PROPERTY: true,
+
+ lowercase: true,
+ uppercase: true,
+ manualLowercase: true,
+ manualUppercase: true,
+ nodeName_: true,
+ isArrayLike: true,
+ forEach: true,
+ sortedKeys: true,
+ forEachSorted: true,
+ reverseParams: true,
+ nextUid: true,
+ setHashKey: true,
+ extend: true,
+ int: true,
+ inherit: true,
+ noop: true,
+ identity: true,
+ valueFn: true,
+ isUndefined: true,
+ isDefined: true,
+ isObject: true,
+ isString: true,
+ isNumber: true,
+ isDate: true,
+ isArray: true,
+ isFunction: true,
+ isRegExp: true,
+ isWindow: true,
+ isScope: true,
+ isFile: true,
+ isFormData: true,
+ isBlob: true,
+ isBoolean: true,
+ isPromiseLike: true,
+ trim: true,
+ escapeForRegexp: true,
+ isElement: true,
+ makeMap: true,
+ includes: true,
+ arrayRemove: true,
+ copy: true,
+ shallowCopy: true,
+ equals: true,
+ csp: true,
+ concat: true,
+ sliceArgs: true,
+ bind: true,
+ toJsonReplacer: true,
+ toJson: true,
+ fromJson: true,
+ startingTag: true,
+ tryDecodeURIComponent: true,
+ parseKeyValue: true,
+ toKeyValue: true,
+ encodeUriSegment: true,
+ encodeUriQuery: true,
+ angularInit: true,
+ bootstrap: true,
+ getTestability: true,
+ snake_case: true,
+ bindJQuery: true,
+ assertArg: true,
+ assertArgFn: true,
+ assertNotHasOwnProperty: true,
+ getter: true,
+ getBlockNodes: true,
+ hasOwnProperty: true,
+ createMap: true,
+
+ NODE_TYPE_ELEMENT: true,
+ NODE_TYPE_TEXT: true,
+ NODE_TYPE_COMMENT: true,
+ NODE_TYPE_DOCUMENT: true,
+ NODE_TYPE_DOCUMENT_FRAGMENT: true,
+*/
+
+////////////////////////////////////
+
+/**
+ * @ngdoc module
+ * @name ng
+ * @module ng
+ * @description
+ *
+ * # ng (core module)
+ * The ng module is loaded by default when an AngularJS application is started. The module itself
+ * contains the essential components for an AngularJS application to function. The table below
+ * lists a high level breakdown of each of the services/factories, filters, directives and testing
+ * components available within this core module.
+ *
+ *
+ */
+
+var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
+
+// The name of a form control's ValidityState property.
+// This is used so that it's possible for internal tests to create mock ValidityStates.
+var VALIDITY_STATE_PROPERTY = 'validity';
+
+/**
+ * @ngdoc function
+ * @name angular.lowercase
+ * @module ng
+ * @kind function
+ *
+ * @description Converts the specified string to lowercase.
+ * @param {string} string String to be converted to lowercase.
+ * @returns {string} Lowercased string.
+ */
+var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+/**
+ * @ngdoc function
+ * @name angular.uppercase
+ * @module ng
+ * @kind function
+ *
+ * @description Converts the specified string to uppercase.
+ * @param {string} string String to be converted to uppercase.
+ * @returns {string} Uppercased string.
+ */
+var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
+
+
+var manualLowercase = function(s) {
+ /* jshint bitwise: false */
+ return isString(s)
+ ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
+ : s;
+};
+var manualUppercase = function(s) {
+ /* jshint bitwise: false */
+ return isString(s)
+ ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
+ : s;
+};
+
+
+// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
+// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
+// with correct but slower alternatives.
+if ('i' !== 'I'.toLowerCase()) {
+ lowercase = manualLowercase;
+ uppercase = manualUppercase;
+}
+
+
+var
+ msie, // holds major version number for IE, or NaN if UA is not IE.
+ jqLite, // delay binding since jQuery could be loaded after us.
+ jQuery, // delay binding
+ slice = [].slice,
+ splice = [].splice,
+ push = [].push,
+ toString = Object.prototype.toString,
+ ngMinErr = minErr('ng'),
+
+ /** @name angular */
+ angular = window.angular || (window.angular = {}),
+ angularModule,
+ uid = 0;
+
+/**
+ * documentMode is an IE-only property
+ * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
+ */
+msie = document.documentMode;
+
+
+/**
+ * @private
+ * @param {*} obj
+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
+ * String ...)
+ */
+function isArrayLike(obj) {
+ if (obj == null || isWindow(obj)) {
+ return false;
+ }
+
+ var length = obj.length;
+
+ if (obj.nodeType === NODE_TYPE_ELEMENT && length) {
+ return true;
+ }
+
+ return isString(obj) || isArray(obj) || length === 0 ||
+ typeof length === 'number' && length > 0 && (length - 1) in obj;
+}
+
+/**
+ * @ngdoc function
+ * @name angular.forEach
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
+ * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
+ * is the value of an object property or an array element, `key` is the object property key or
+ * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
+ *
+ * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
+ * using the `hasOwnProperty` method.
+ *
+ * Unlike ES262's
+ * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
+ * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
+ * return the value provided.
+ *
+ ```js
+ var values = {name: 'misko', gender: 'male'};
+ var log = [];
+ angular.forEach(values, function(value, key) {
+ this.push(key + ': ' + value);
+ }, log);
+ expect(log).toEqual(['name: misko', 'gender: male']);
+ ```
+ *
+ * @param {Object|Array} obj Object to iterate over.
+ * @param {Function} iterator Iterator function.
+ * @param {Object=} context Object to become context (`this`) for the iterator function.
+ * @returns {Object|Array} Reference to `obj`.
+ */
+
+function forEach(obj, iterator, context) {
+ var key, length;
+ if (obj) {
+ if (isFunction(obj)) {
+ for (key in obj) {
+ // Need to check if hasOwnProperty exists,
+ // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
+ if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
+ iterator.call(context, obj[key], key, obj);
+ }
+ }
+ } else if (isArray(obj) || isArrayLike(obj)) {
+ var isPrimitive = typeof obj !== 'object';
+ for (key = 0, length = obj.length; key < length; key++) {
+ if (isPrimitive || key in obj) {
+ iterator.call(context, obj[key], key, obj);
+ }
+ }
+ } else if (obj.forEach && obj.forEach !== forEach) {
+ obj.forEach(iterator, context, obj);
+ } else {
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ iterator.call(context, obj[key], key, obj);
+ }
+ }
+ }
+ }
+ return obj;
+}
+
+function sortedKeys(obj) {
+ return Object.keys(obj).sort();
+}
+
+function forEachSorted(obj, iterator, context) {
+ var keys = sortedKeys(obj);
+ for (var i = 0; i < keys.length; i++) {
+ iterator.call(context, obj[keys[i]], keys[i]);
+ }
+ return keys;
+}
+
+
+/**
+ * when using forEach the params are value, key, but it is often useful to have key, value.
+ * @param {function(string, *)} iteratorFn
+ * @returns {function(*, string)}
+ */
+function reverseParams(iteratorFn) {
+ return function(value, key) { iteratorFn(key, value); };
+}
+
+/**
+ * A consistent way of creating unique IDs in angular.
+ *
+ * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
+ * we hit number precision issues in JavaScript.
+ *
+ * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
+ *
+ * @returns {number} an unique alpha-numeric string
+ */
+function nextUid() {
+ return ++uid;
+}
+
+
+/**
+ * Set or clear the hashkey for an object.
+ * @param obj object
+ * @param h the hashkey (!truthy to delete the hashkey)
+ */
+function setHashKey(obj, h) {
+ if (h) {
+ obj.$$hashKey = h;
+ }
+ else {
+ delete obj.$$hashKey;
+ }
+}
+
+/**
+ * @ngdoc function
+ * @name angular.extend
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
+ * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
+ * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
+ * Note: Keep in mind that `angular.extend` does not support recursive merge (deep copy).
+ *
+ * @param {Object} dst Destination object.
+ * @param {...Object} src Source object(s).
+ * @returns {Object} Reference to `dst`.
+ */
+function extend(dst) {
+ var h = dst.$$hashKey;
+
+ for (var i = 1, ii = arguments.length; i < ii; i++) {
+ var obj = arguments[i];
+ if (obj) {
+ var keys = Object.keys(obj);
+ for (var j = 0, jj = keys.length; j < jj; j++) {
+ var key = keys[j];
+ dst[key] = obj[key];
+ }
+ }
+ }
+
+ setHashKey(dst, h);
+ return dst;
+}
+
+function int(str) {
+ return parseInt(str, 10);
+}
+
+
+function inherit(parent, extra) {
+ return extend(Object.create(parent), extra);
+}
+
+/**
+ * @ngdoc function
+ * @name angular.noop
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * A function that performs no operations. This function can be useful when writing code in the
+ * functional style.
+ ```js
+ function foo(callback) {
+ var result = calculateResult();
+ (callback || angular.noop)(result);
+ }
+ ```
+ */
+function noop() {}
+noop.$inject = [];
+
+
+/**
+ * @ngdoc function
+ * @name angular.identity
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * A function that returns its first argument. This function is useful when writing code in the
+ * functional style.
+ *
+ ```js
+ function transformer(transformationFn, value) {
+ return (transformationFn || angular.identity)(value);
+ };
+ ```
+ * @param {*} value to be returned.
+ * @returns {*} the value passed in.
+ */
+function identity($) {return $;}
+identity.$inject = [];
+
+
+function valueFn(value) {return function() {return value;};}
+
+/**
+ * @ngdoc function
+ * @name angular.isUndefined
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is undefined.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is undefined.
+ */
+function isUndefined(value) {return typeof value === 'undefined';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isDefined
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is defined.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is defined.
+ */
+function isDefined(value) {return typeof value !== 'undefined';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isObject
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
+ * considered to be objects. Note that JavaScript arrays are objects.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is an `Object` but not `null`.
+ */
+function isObject(value) {
+ // http://jsperf.com/isobject4
+ return value !== null && typeof value === 'object';
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isString
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a `String`.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `String`.
+ */
+function isString(value) {return typeof value === 'string';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isNumber
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a `Number`.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `Number`.
+ */
+function isNumber(value) {return typeof value === 'number';}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isDate
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a value is a date.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `Date`.
+ */
+function isDate(value) {
+ return toString.call(value) === '[object Date]';
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.isArray
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is an `Array`.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is an `Array`.
+ */
+var isArray = Array.isArray;
+
+/**
+ * @ngdoc function
+ * @name angular.isFunction
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if a reference is a `Function`.
+ *
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `Function`.
+ */
+function isFunction(value) {return typeof value === 'function';}
+
+
+/**
+ * Determines if a value is a regular expression object.
+ *
+ * @private
+ * @param {*} value Reference to check.
+ * @returns {boolean} True if `value` is a `RegExp`.
+ */
+function isRegExp(value) {
+ return toString.call(value) === '[object RegExp]';
+}
+
+
+/**
+ * Checks if `obj` is a window object.
+ *
+ * @private
+ * @param {*} obj Object to check
+ * @returns {boolean} True if `obj` is a window obj.
+ */
+function isWindow(obj) {
+ return obj && obj.window === obj;
+}
+
+
+function isScope(obj) {
+ return obj && obj.$evalAsync && obj.$watch;
+}
+
+
+function isFile(obj) {
+ return toString.call(obj) === '[object File]';
+}
+
+
+function isFormData(obj) {
+ return toString.call(obj) === '[object FormData]';
+}
+
+
+function isBlob(obj) {
+ return toString.call(obj) === '[object Blob]';
+}
+
+
+function isBoolean(value) {
+ return typeof value === 'boolean';
+}
+
+
+function isPromiseLike(obj) {
+ return obj && isFunction(obj.then);
+}
+
+
+var trim = function(value) {
+ return isString(value) ? value.trim() : value;
+};
+
+// Copied from:
+// http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
+// Prereq: s is a string.
+var escapeForRegexp = function(s) {
+ return s.replace(/([-()\[\]{}+?*.$\^|,:#= 0)
+ array.splice(index, 1);
+ return value;
+}
+
+/**
+ * @ngdoc function
+ * @name angular.copy
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Creates a deep copy of `source`, which should be an object or an array.
+ *
+ * * If no destination is supplied, a copy of the object or array is created.
+ * * If a destination is provided, all of its elements (for arrays) or properties (for objects)
+ * are deleted and then all elements/properties from the source are copied to it.
+ * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
+ * * If `source` is identical to 'destination' an exception will be thrown.
+ *
+ * @param {*} source The source that will be used to make a copy.
+ * Can be any type, including primitives, `null`, and `undefined`.
+ * @param {(Object|Array)=} destination Destination into which the source is copied. If
+ * provided, must be of the same type as `source`.
+ * @returns {*} The copy or updated `destination`, if `destination` was specified.
+ *
+ * @example
+
+
+
+
+
form = {{user | json}}
+
master = {{master | json}}
+
+
+
+
+
+ */
+function copy(source, destination, stackSource, stackDest) {
+ if (isWindow(source) || isScope(source)) {
+ throw ngMinErr('cpws',
+ "Can't copy! Making copies of Window or Scope instances is not supported.");
+ }
+
+ if (!destination) {
+ destination = source;
+ if (source) {
+ if (isArray(source)) {
+ destination = copy(source, [], stackSource, stackDest);
+ } else if (isDate(source)) {
+ destination = new Date(source.getTime());
+ } else if (isRegExp(source)) {
+ destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
+ destination.lastIndex = source.lastIndex;
+ } else if (isObject(source)) {
+ var emptyObject = Object.create(Object.getPrototypeOf(source));
+ destination = copy(source, emptyObject, stackSource, stackDest);
+ }
+ }
+ } else {
+ if (source === destination) throw ngMinErr('cpi',
+ "Can't copy! Source and destination are identical.");
+
+ stackSource = stackSource || [];
+ stackDest = stackDest || [];
+
+ if (isObject(source)) {
+ var index = stackSource.indexOf(source);
+ if (index !== -1) return stackDest[index];
+
+ stackSource.push(source);
+ stackDest.push(destination);
+ }
+
+ var result;
+ if (isArray(source)) {
+ destination.length = 0;
+ for (var i = 0; i < source.length; i++) {
+ result = copy(source[i], null, stackSource, stackDest);
+ if (isObject(source[i])) {
+ stackSource.push(source[i]);
+ stackDest.push(result);
+ }
+ destination.push(result);
+ }
+ } else {
+ var h = destination.$$hashKey;
+ if (isArray(destination)) {
+ destination.length = 0;
+ } else {
+ forEach(destination, function(value, key) {
+ delete destination[key];
+ });
+ }
+ for (var key in source) {
+ if (source.hasOwnProperty(key)) {
+ result = copy(source[key], null, stackSource, stackDest);
+ if (isObject(source[key])) {
+ stackSource.push(source[key]);
+ stackDest.push(result);
+ }
+ destination[key] = result;
+ }
+ }
+ setHashKey(destination,h);
+ }
+
+ }
+ return destination;
+}
+
+/**
+ * Creates a shallow copy of an object, an array or a primitive.
+ *
+ * Assumes that there are no proto properties for objects.
+ */
+function shallowCopy(src, dst) {
+ if (isArray(src)) {
+ dst = dst || [];
+
+ for (var i = 0, ii = src.length; i < ii; i++) {
+ dst[i] = src[i];
+ }
+ } else if (isObject(src)) {
+ dst = dst || {};
+
+ for (var key in src) {
+ if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
+ dst[key] = src[key];
+ }
+ }
+ }
+
+ return dst || src;
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.equals
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Determines if two objects or two values are equivalent. Supports value types, regular
+ * expressions, arrays and objects.
+ *
+ * Two objects or values are considered equivalent if at least one of the following is true:
+ *
+ * * Both objects or values pass `===` comparison.
+ * * Both objects or values are of the same type and all of their properties are equal by
+ * comparing them with `angular.equals`.
+ * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
+ * * Both values represent the same regular expression (In JavaScript,
+ * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
+ * representation matches).
+ *
+ * During a property comparison, properties of `function` type and properties with names
+ * that begin with `$` are ignored.
+ *
+ * Scope and DOMWindow objects are being compared only by identify (`===`).
+ *
+ * @param {*} o1 Object or value to compare.
+ * @param {*} o2 Object or value to compare.
+ * @returns {boolean} True if arguments are equal.
+ */
+function equals(o1, o2) {
+ if (o1 === o2) return true;
+ if (o1 === null || o2 === null) return false;
+ if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
+ var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
+ if (t1 == t2) {
+ if (t1 == 'object') {
+ if (isArray(o1)) {
+ if (!isArray(o2)) return false;
+ if ((length = o1.length) == o2.length) {
+ for (key = 0; key < length; key++) {
+ if (!equals(o1[key], o2[key])) return false;
+ }
+ return true;
+ }
+ } else if (isDate(o1)) {
+ if (!isDate(o2)) return false;
+ return equals(o1.getTime(), o2.getTime());
+ } else if (isRegExp(o1) && isRegExp(o2)) {
+ return o1.toString() == o2.toString();
+ } else {
+ if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
+ keySet = {};
+ for (key in o1) {
+ if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
+ if (!equals(o1[key], o2[key])) return false;
+ keySet[key] = true;
+ }
+ for (key in o2) {
+ if (!keySet.hasOwnProperty(key) &&
+ key.charAt(0) !== '$' &&
+ o2[key] !== undefined &&
+ !isFunction(o2[key])) return false;
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+var csp = function() {
+ if (isDefined(csp.isActive_)) return csp.isActive_;
+
+ var active = !!(document.querySelector('[ng-csp]') ||
+ document.querySelector('[data-ng-csp]'));
+
+ if (!active) {
+ try {
+ /* jshint -W031, -W054 */
+ new Function('');
+ /* jshint +W031, +W054 */
+ } catch (e) {
+ active = true;
+ }
+ }
+
+ return (csp.isActive_ = active);
+};
+
+
+
+function concat(array1, array2, index) {
+ return array1.concat(slice.call(array2, index));
+}
+
+function sliceArgs(args, startIndex) {
+ return slice.call(args, startIndex || 0);
+}
+
+
+/* jshint -W101 */
+/**
+ * @ngdoc function
+ * @name angular.bind
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
+ * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
+ * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
+ * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
+ *
+ * @param {Object} self Context which `fn` should be evaluated in.
+ * @param {function()} fn Function to be bound.
+ * @param {...*} args Optional arguments to be prebound to the `fn` function call.
+ * @returns {function()} Function that wraps the `fn` with all the specified bindings.
+ */
+/* jshint +W101 */
+function bind(self, fn) {
+ var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
+ if (isFunction(fn) && !(fn instanceof RegExp)) {
+ return curryArgs.length
+ ? function() {
+ return arguments.length
+ ? fn.apply(self, concat(curryArgs, arguments, 0))
+ : fn.apply(self, curryArgs);
+ }
+ : function() {
+ return arguments.length
+ ? fn.apply(self, arguments)
+ : fn.call(self);
+ };
+ } else {
+ // in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
+ return fn;
+ }
+}
+
+
+function toJsonReplacer(key, value) {
+ var val = value;
+
+ if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
+ val = undefined;
+ } else if (isWindow(value)) {
+ val = '$WINDOW';
+ } else if (value && document === value) {
+ val = '$DOCUMENT';
+ } else if (isScope(value)) {
+ val = '$SCOPE';
+ }
+
+ return val;
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.toJson
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
+ * stripped since angular uses this notation internally.
+ *
+ * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
+ * @param {boolean|number=} pretty If set to true, the JSON output will contain newlines and whitespace.
+ * If set to an integer, the JSON output will contain that many spaces per indentation (the default is 2).
+ * @returns {string|undefined} JSON-ified string representing `obj`.
+ */
+function toJson(obj, pretty) {
+ if (typeof obj === 'undefined') return undefined;
+ if (!isNumber(pretty)) {
+ pretty = pretty ? 2 : null;
+ }
+ return JSON.stringify(obj, toJsonReplacer, pretty);
+}
+
+
+/**
+ * @ngdoc function
+ * @name angular.fromJson
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Deserializes a JSON string.
+ *
+ * @param {string} json JSON string to deserialize.
+ * @returns {Object|Array|string|number} Deserialized JSON string.
+ */
+function fromJson(json) {
+ return isString(json)
+ ? JSON.parse(json)
+ : json;
+}
+
+
+/**
+ * @returns {string} Returns the string representation of the element.
+ */
+function startingTag(element) {
+ element = jqLite(element).clone();
+ try {
+ // turns out IE does not let you set .html() on elements which
+ // are not allowed to have children. So we just ignore it.
+ element.empty();
+ } catch (e) {}
+ var elemHtml = jqLite('
').append(element).html();
+ try {
+ return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
+ elemHtml.
+ match(/^(<[^>]+>)/)[1].
+ replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
+ } catch (e) {
+ return lowercase(elemHtml);
+ }
+
+}
+
+
+/////////////////////////////////////////////////
+
+/**
+ * Tries to decode the URI component without throwing an exception.
+ *
+ * @private
+ * @param str value potential URI component to check.
+ * @returns {boolean} True if `value` can be decoded
+ * with the decodeURIComponent function.
+ */
+function tryDecodeURIComponent(value) {
+ try {
+ return decodeURIComponent(value);
+ } catch (e) {
+ // Ignore any invalid uri component
+ }
+}
+
+
+/**
+ * Parses an escaped url query string into key-value pairs.
+ * @returns {Object.}
+ */
+function parseKeyValue(/**string*/keyValue) {
+ var obj = {}, key_value, key;
+ forEach((keyValue || "").split('&'), function(keyValue) {
+ if (keyValue) {
+ key_value = keyValue.replace(/\+/g,'%20').split('=');
+ key = tryDecodeURIComponent(key_value[0]);
+ if (isDefined(key)) {
+ var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
+ if (!hasOwnProperty.call(obj, key)) {
+ obj[key] = val;
+ } else if (isArray(obj[key])) {
+ obj[key].push(val);
+ } else {
+ obj[key] = [obj[key],val];
+ }
+ }
+ }
+ });
+ return obj;
+}
+
+function toKeyValue(obj) {
+ var parts = [];
+ forEach(obj, function(value, key) {
+ if (isArray(value)) {
+ forEach(value, function(arrayValue) {
+ parts.push(encodeUriQuery(key, true) +
+ (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
+ });
+ } else {
+ parts.push(encodeUriQuery(key, true) +
+ (value === true ? '' : '=' + encodeUriQuery(value, true)));
+ }
+ });
+ return parts.length ? parts.join('&') : '';
+}
+
+
+/**
+ * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
+ * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
+ * segments:
+ * segment = *pchar
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+ * pct-encoded = "%" HEXDIG HEXDIG
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+ * / "*" / "+" / "," / ";" / "="
+ */
+function encodeUriSegment(val) {
+ return encodeUriQuery(val, true).
+ replace(/%26/gi, '&').
+ replace(/%3D/gi, '=').
+ replace(/%2B/gi, '+');
+}
+
+
+/**
+ * This method is intended for encoding *key* or *value* parts of query component. We need a custom
+ * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
+ * encoded per http://tools.ietf.org/html/rfc3986:
+ * query = *( pchar / "/" / "?" )
+ * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+ * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ * pct-encoded = "%" HEXDIG HEXDIG
+ * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+ * / "*" / "+" / "," / ";" / "="
+ */
+function encodeUriQuery(val, pctEncodeSpaces) {
+ return encodeURIComponent(val).
+ replace(/%40/gi, '@').
+ replace(/%3A/gi, ':').
+ replace(/%24/g, '$').
+ replace(/%2C/gi, ',').
+ replace(/%3B/gi, ';').
+ replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
+}
+
+var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
+
+function getNgAttribute(element, ngAttr) {
+ var attr, i, ii = ngAttrPrefixes.length;
+ element = jqLite(element);
+ for (i = 0; i < ii; ++i) {
+ attr = ngAttrPrefixes[i] + ngAttr;
+ if (isString(attr = element.attr(attr))) {
+ return attr;
+ }
+ }
+ return null;
+}
+
+/**
+ * @ngdoc directive
+ * @name ngApp
+ * @module ng
+ *
+ * @element ANY
+ * @param {angular.Module} ngApp an optional application
+ * {@link angular.module module} name to load.
+ * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
+ * created in "strict-di" mode. This means that the application will fail to invoke functions which
+ * do not use explicit function annotation (and are thus unsuitable for minification), as described
+ * in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
+ * tracking down the root of these bugs.
+ *
+ * @description
+ *
+ * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
+ * designates the **root element** of the application and is typically placed near the root element
+ * of the page - e.g. on the `` or `` tags.
+ *
+ * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
+ * found in the document will be used to define the root element to auto-bootstrap as an
+ * application. To run multiple applications in an HTML document you must manually bootstrap them using
+ * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
+ *
+ * You can specify an **AngularJS module** to be used as the root module for the application. This
+ * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
+ * should contain the application code needed or have dependencies on other modules that will
+ * contain the code. See {@link angular.module} for more information.
+ *
+ * In the example below if the `ngApp` directive were not placed on the `html` element then the
+ * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
+ * would not be resolved to `3`.
+ *
+ * `ngApp` is the easiest, and most common way to bootstrap an application.
+ *
+
+
+
+ I can add: {{a}} + {{b}} = {{ a+b }}
+
+
+
+ angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
+ $scope.a = 1;
+ $scope.b = 2;
+ });
+
+
+ *
+ * Using `ngStrictDi`, you would see something like this:
+ *
+
+
+
+
+ I can add: {{a}} + {{b}} = {{ a+b }}
+
+
This renders because the controller does not fail to
+ instantiate, by using explicit annotation style (see
+ script.js for details)
+
+
+
+
+ Name:
+ Hello, {{name}}!
+
+
This renders because the controller does not fail to
+ instantiate, by using explicit annotation style
+ (see script.js for details)
+
+
+
+
+ I can add: {{a}} + {{b}} = {{ a+b }}
+
+
The controller could not be instantiated, due to relying
+ on automatic function annotations (which are disabled in
+ strict mode). As such, the content of this section is not
+ interpolated, and there should be an error in your web console.
+
+
+
+
+
+ angular.module('ngAppStrictDemo', [])
+ // BadController will fail to instantiate, due to relying on automatic function annotation,
+ // rather than an explicit annotation
+ .controller('BadController', function($scope) {
+ $scope.a = 1;
+ $scope.b = 2;
+ })
+ // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
+ // due to using explicit annotations using the array style and $inject property, respectively.
+ .controller('GoodController1', ['$scope', function($scope) {
+ $scope.a = 1;
+ $scope.b = 2;
+ }])
+ .controller('GoodController2', GoodController2);
+ function GoodController2($scope) {
+ $scope.name = "World";
+ }
+ GoodController2.$inject = ['$scope'];
+
+
+ div[ng-controller] {
+ margin-bottom: 1em;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ border: 1px solid;
+ padding: .5em;
+ }
+ div[ng-controller^=Good] {
+ border-color: #d6e9c6;
+ background-color: #dff0d8;
+ color: #3c763d;
+ }
+ div[ng-controller^=Bad] {
+ border-color: #ebccd1;
+ background-color: #f2dede;
+ color: #a94442;
+ margin-bottom: 0;
+ }
+
+
+ */
+function angularInit(element, bootstrap) {
+ var appElement,
+ module,
+ config = {};
+
+ // The element `element` has priority over any other element
+ forEach(ngAttrPrefixes, function(prefix) {
+ var name = prefix + 'app';
+
+ if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
+ appElement = element;
+ module = element.getAttribute(name);
+ }
+ });
+ forEach(ngAttrPrefixes, function(prefix) {
+ var name = prefix + 'app';
+ var candidate;
+
+ if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
+ appElement = candidate;
+ module = candidate.getAttribute(name);
+ }
+ });
+ if (appElement) {
+ config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
+ bootstrap(appElement, module ? [module] : [], config);
+ }
+}
+
+/**
+ * @ngdoc function
+ * @name angular.bootstrap
+ * @module ng
+ * @description
+ * Use this function to manually start up angular application.
+ *
+ * See: {@link guide/bootstrap Bootstrap}
+ *
+ * Note that Protractor based end-to-end tests cannot use this function to bootstrap manually.
+ * They must use {@link ng.directive:ngApp ngApp}.
+ *
+ * Angular will detect if it has been loaded into the browser more than once and only allow the
+ * first loaded script to be bootstrapped and will report a warning to the browser console for
+ * each of the subsequent scripts. This prevents strange results in applications, where otherwise
+ * multiple instances of Angular try to work on the DOM.
+ *
+ * ```html
+ *
+ *
+ *
+ *
+ * {{greeting}}
+ *
+ *
+ *
+ *
+ *
+ *
+ * ```
+ *
+ * @param {DOMElement} element DOM element which is the root of angular application.
+ * @param {Array=} modules an array of modules to load into the application.
+ * Each item in the array should be the name of a predefined module or a (DI annotated)
+ * function that will be invoked by the injector as a run block.
+ * See: {@link angular.module modules}
+ * @param {Object=} config an object for defining configuration options for the application. The
+ * following keys are supported:
+ *
+ * * `strictDi` - disable automatic function annotation for the application. This is meant to
+ * assist in finding bugs which break minified code. Defaults to `false`.
+ *
+ * @returns {auto.$injector} Returns the newly created injector for this app.
+ */
+function bootstrap(element, modules, config) {
+ if (!isObject(config)) config = {};
+ var defaultConfig = {
+ strictDi: false
+ };
+ config = extend(defaultConfig, config);
+ var doBootstrap = function() {
+ element = jqLite(element);
+
+ if (element.injector()) {
+ var tag = (element[0] === document) ? 'document' : startingTag(element);
+ //Encode angle brackets to prevent input from being sanitized to empty string #8683
+ throw ngMinErr(
+ 'btstrpd',
+ "App Already Bootstrapped with this Element '{0}'",
+ tag.replace(/,'<').replace(/>/,'>'));
+ }
+
+ modules = modules || [];
+ modules.unshift(['$provide', function($provide) {
+ $provide.value('$rootElement', element);
+ }]);
+
+ if (config.debugInfoEnabled) {
+ // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
+ modules.push(['$compileProvider', function($compileProvider) {
+ $compileProvider.debugInfoEnabled(true);
+ }]);
+ }
+
+ modules.unshift('ng');
+ var injector = createInjector(modules, config.strictDi);
+ injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
+ function bootstrapApply(scope, element, compile, injector) {
+ scope.$apply(function() {
+ element.data('$injector', injector);
+ compile(element)(scope);
+ });
+ }]
+ );
+ return injector;
+ };
+
+ var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
+ var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
+
+ if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
+ config.debugInfoEnabled = true;
+ window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
+ }
+
+ if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
+ return doBootstrap();
+ }
+
+ window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
+ angular.resumeBootstrap = function(extraModules) {
+ forEach(extraModules, function(module) {
+ modules.push(module);
+ });
+ doBootstrap();
+ };
+}
+
+/**
+ * @ngdoc function
+ * @name angular.reloadWithDebugInfo
+ * @module ng
+ * @description
+ * Use this function to reload the current application with debug information turned on.
+ * This takes precedence over a call to `$compileProvider.debugInfoEnabled(false)`.
+ *
+ * See {@link ng.$compileProvider#debugInfoEnabled} for more.
+ */
+function reloadWithDebugInfo() {
+ window.name = 'NG_ENABLE_DEBUG_INFO!' + window.name;
+ window.location.reload();
+}
+
+/**
+ * @name angular.getTestability
+ * @module ng
+ * @description
+ * Get the testability service for the instance of Angular on the given
+ * element.
+ * @param {DOMElement} element DOM element which is the root of angular application.
+ */
+function getTestability(rootElement) {
+ var injector = angular.element(rootElement).injector();
+ if (!injector) {
+ throw ngMinErr('test',
+ 'no injector found for element argument to getTestability');
+ }
+ return injector.get('$$testability');
+}
+
+var SNAKE_CASE_REGEXP = /[A-Z]/g;
+function snake_case(name, separator) {
+ separator = separator || '_';
+ return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
+ return (pos ? separator : '') + letter.toLowerCase();
+ });
+}
+
+var bindJQueryFired = false;
+var skipDestroyOnNextJQueryCleanData;
+function bindJQuery() {
+ var originalCleanData;
+
+ if (bindJQueryFired) {
+ return;
+ }
+
+ // bind to jQuery if present;
+ jQuery = window.jQuery;
+ // Use jQuery if it exists with proper functionality, otherwise default to us.
+ // Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
+ // Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
+ // versions. It will not work for sure with jQuery <1.7, though.
+ if (jQuery && jQuery.fn.on) {
+ jqLite = jQuery;
+ extend(jQuery.fn, {
+ scope: JQLitePrototype.scope,
+ isolateScope: JQLitePrototype.isolateScope,
+ controller: JQLitePrototype.controller,
+ injector: JQLitePrototype.injector,
+ inheritedData: JQLitePrototype.inheritedData
+ });
+
+ // All nodes removed from the DOM via various jQuery APIs like .remove()
+ // are passed through jQuery.cleanData. Monkey-patch this method to fire
+ // the $destroy event on all removed nodes.
+ originalCleanData = jQuery.cleanData;
+ jQuery.cleanData = function(elems) {
+ var events;
+ if (!skipDestroyOnNextJQueryCleanData) {
+ for (var i = 0, elem; (elem = elems[i]) != null; i++) {
+ events = jQuery._data(elem, "events");
+ if (events && events.$destroy) {
+ jQuery(elem).triggerHandler('$destroy');
+ }
+ }
+ } else {
+ skipDestroyOnNextJQueryCleanData = false;
+ }
+ originalCleanData(elems);
+ };
+ } else {
+ jqLite = JQLite;
+ }
+
+ angular.element = jqLite;
+
+ // Prevent double-proxying.
+ bindJQueryFired = true;
+}
+
+/**
+ * throw error if the argument is falsy.
+ */
+function assertArg(arg, name, reason) {
+ if (!arg) {
+ throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
+ }
+ return arg;
+}
+
+function assertArgFn(arg, name, acceptArrayAnnotation) {
+ if (acceptArrayAnnotation && isArray(arg)) {
+ arg = arg[arg.length - 1];
+ }
+
+ assertArg(isFunction(arg), name, 'not a function, got ' +
+ (arg && typeof arg === 'object' ? arg.constructor.name || 'Object' : typeof arg));
+ return arg;
+}
+
+/**
+ * throw error if the name given is hasOwnProperty
+ * @param {String} name the name to test
+ * @param {String} context the context in which the name is used, such as module or directive
+ */
+function assertNotHasOwnProperty(name, context) {
+ if (name === 'hasOwnProperty') {
+ throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context);
+ }
+}
+
+/**
+ * Return the value accessible from the object by path. Any undefined traversals are ignored
+ * @param {Object} obj starting object
+ * @param {String} path path to traverse
+ * @param {boolean} [bindFnToScope=true]
+ * @returns {Object} value as accessible by path
+ */
+//TODO(misko): this function needs to be removed
+function getter(obj, path, bindFnToScope) {
+ if (!path) return obj;
+ var keys = path.split('.');
+ var key;
+ var lastInstance = obj;
+ var len = keys.length;
+
+ for (var i = 0; i < len; i++) {
+ key = keys[i];
+ if (obj) {
+ obj = (lastInstance = obj)[key];
+ }
+ }
+ if (!bindFnToScope && isFunction(obj)) {
+ return bind(lastInstance, obj);
+ }
+ return obj;
+}
+
+/**
+ * Return the DOM siblings between the first and last node in the given array.
+ * @param {Array} array like object
+ * @returns {jqLite} jqLite collection containing the nodes
+ */
+function getBlockNodes(nodes) {
+ // TODO(perf): just check if all items in `nodes` are siblings and if they are return the original
+ // collection, otherwise update the original collection.
+ var node = nodes[0];
+ var endNode = nodes[nodes.length - 1];
+ var blockNodes = [node];
+
+ do {
+ node = node.nextSibling;
+ if (!node) break;
+ blockNodes.push(node);
+ } while (node !== endNode);
+
+ return jqLite(blockNodes);
+}
+
+
+/**
+ * Creates a new object without a prototype. This object is useful for lookup without having to
+ * guard against prototypically inherited properties via hasOwnProperty.
+ *
+ * Related micro-benchmarks:
+ * - http://jsperf.com/object-create2
+ * - http://jsperf.com/proto-map-lookup/2
+ * - http://jsperf.com/for-in-vs-object-keys2
+ *
+ * @returns {Object}
+ */
+function createMap() {
+ return Object.create(null);
+}
+
+var NODE_TYPE_ELEMENT = 1;
+var NODE_TYPE_TEXT = 3;
+var NODE_TYPE_COMMENT = 8;
+var NODE_TYPE_DOCUMENT = 9;
+var NODE_TYPE_DOCUMENT_FRAGMENT = 11;
+
+/**
+ * @ngdoc type
+ * @name angular.Module
+ * @module ng
+ * @description
+ *
+ * Interface for configuring angular {@link angular.module modules}.
+ */
+
+function setupModuleLoader(window) {
+
+ var $injectorMinErr = minErr('$injector');
+ var ngMinErr = minErr('ng');
+
+ function ensure(obj, name, factory) {
+ return obj[name] || (obj[name] = factory());
+ }
+
+ var angular = ensure(window, 'angular', Object);
+
+ // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
+ angular.$$minErr = angular.$$minErr || minErr;
+
+ return ensure(angular, 'module', function() {
+ /** @type {Object.} */
+ var modules = {};
+
+ /**
+ * @ngdoc function
+ * @name angular.module
+ * @module ng
+ * @description
+ *
+ * The `angular.module` is a global place for creating, registering and retrieving Angular
+ * modules.
+ * All modules (angular core or 3rd party) that should be available to an application must be
+ * registered using this mechanism.
+ *
+ * When passed two or more arguments, a new module is created. If passed only one argument, an
+ * existing module (the name passed as the first argument to `module`) is retrieved.
+ *
+ *
+ * # Module
+ *
+ * A module is a collection of services, directives, controllers, filters, and configuration information.
+ * `angular.module` is used to configure the {@link auto.$injector $injector}.
+ *
+ * ```js
+ * // Create a new module
+ * var myModule = angular.module('myModule', []);
+ *
+ * // register a new service
+ * myModule.value('appName', 'MyCoolApp');
+ *
+ * // configure existing services inside initialization blocks.
+ * myModule.config(['$locationProvider', function($locationProvider) {
+ * // Configure existing providers
+ * $locationProvider.hashPrefix('!');
+ * }]);
+ * ```
+ *
+ * Then you can create an injector and load your modules like this:
+ *
+ * ```js
+ * var injector = angular.injector(['ng', 'myModule'])
+ * ```
+ *
+ * However it's more likely that you'll just use
+ * {@link ng.directive:ngApp ngApp} or
+ * {@link angular.bootstrap} to simplify this process for you.
+ *
+ * @param {!string} name The name of the module to create or retrieve.
+ * @param {!Array.=} requires If specified then new module is being created. If
+ * unspecified then the module is being retrieved for further configuration.
+ * @param {Function=} configFn Optional configuration function for the module. Same as
+ * {@link angular.Module#config Module#config()}.
+ * @returns {module} new module with the {@link angular.Module} api.
+ */
+ return function module(name, requires, configFn) {
+ var assertNotHasOwnProperty = function(name, context) {
+ if (name === 'hasOwnProperty') {
+ throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
+ }
+ };
+
+ assertNotHasOwnProperty(name, 'module');
+ if (requires && modules.hasOwnProperty(name)) {
+ modules[name] = null;
+ }
+ return ensure(modules, name, function() {
+ if (!requires) {
+ throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
+ "the module name or forgot to load it. If registering a module ensure that you " +
+ "specify the dependencies as the second argument.", name);
+ }
+
+ /** @type {!Array.>} */
+ var invokeQueue = [];
+
+ /** @type {!Array.} */
+ var configBlocks = [];
+
+ /** @type {!Array.} */
+ var runBlocks = [];
+
+ var config = invokeLater('$injector', 'invoke', 'push', configBlocks);
+
+ /** @type {angular.Module} */
+ var moduleInstance = {
+ // Private state
+ _invokeQueue: invokeQueue,
+ _configBlocks: configBlocks,
+ _runBlocks: runBlocks,
+
+ /**
+ * @ngdoc property
+ * @name angular.Module#requires
+ * @module ng
+ *
+ * @description
+ * Holds the list of modules which the injector will load before the current module is
+ * loaded.
+ */
+ requires: requires,
+
+ /**
+ * @ngdoc property
+ * @name angular.Module#name
+ * @module ng
+ *
+ * @description
+ * Name of the module.
+ */
+ name: name,
+
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#provider
+ * @module ng
+ * @param {string} name service name
+ * @param {Function} providerType Construction function for creating new instance of the
+ * service.
+ * @description
+ * See {@link auto.$provide#provider $provide.provider()}.
+ */
+ provider: invokeLater('$provide', 'provider'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#factory
+ * @module ng
+ * @param {string} name service name
+ * @param {Function} providerFunction Function for creating new instance of the service.
+ * @description
+ * See {@link auto.$provide#factory $provide.factory()}.
+ */
+ factory: invokeLater('$provide', 'factory'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#service
+ * @module ng
+ * @param {string} name service name
+ * @param {Function} constructor A constructor function that will be instantiated.
+ * @description
+ * See {@link auto.$provide#service $provide.service()}.
+ */
+ service: invokeLater('$provide', 'service'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#value
+ * @module ng
+ * @param {string} name service name
+ * @param {*} object Service instance object.
+ * @description
+ * See {@link auto.$provide#value $provide.value()}.
+ */
+ value: invokeLater('$provide', 'value'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#constant
+ * @module ng
+ * @param {string} name constant name
+ * @param {*} object Constant value.
+ * @description
+ * Because the constant are fixed, they get applied before other provide methods.
+ * See {@link auto.$provide#constant $provide.constant()}.
+ */
+ constant: invokeLater('$provide', 'constant', 'unshift'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#animation
+ * @module ng
+ * @param {string} name animation name
+ * @param {Function} animationFactory Factory function for creating new instance of an
+ * animation.
+ * @description
+ *
+ * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
+ *
+ *
+ * Defines an animation hook that can be later used with
+ * {@link ngAnimate.$animate $animate} service and directives that use this service.
+ *
+ * ```js
+ * module.animation('.animation-name', function($inject1, $inject2) {
+ * return {
+ * eventName : function(element, done) {
+ * //code to run the animation
+ * //once complete, then run done()
+ * return function cancellationFunction(element) {
+ * //code to cancel the animation
+ * }
+ * }
+ * }
+ * })
+ * ```
+ *
+ * See {@link ng.$animateProvider#register $animateProvider.register()} and
+ * {@link ngAnimate ngAnimate module} for more information.
+ */
+ animation: invokeLater('$animateProvider', 'register'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#filter
+ * @module ng
+ * @param {string} name Filter name.
+ * @param {Function} filterFactory Factory function for creating new instance of filter.
+ * @description
+ * See {@link ng.$filterProvider#register $filterProvider.register()}.
+ */
+ filter: invokeLater('$filterProvider', 'register'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#controller
+ * @module ng
+ * @param {string|Object} name Controller name, or an object map of controllers where the
+ * keys are the names and the values are the constructors.
+ * @param {Function} constructor Controller constructor function.
+ * @description
+ * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
+ */
+ controller: invokeLater('$controllerProvider', 'register'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#directive
+ * @module ng
+ * @param {string|Object} name Directive name, or an object map of directives where the
+ * keys are the names and the values are the factories.
+ * @param {Function} directiveFactory Factory function for creating new instance of
+ * directives.
+ * @description
+ * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
+ */
+ directive: invokeLater('$compileProvider', 'directive'),
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#config
+ * @module ng
+ * @param {Function} configFn Execute this function on module load. Useful for service
+ * configuration.
+ * @description
+ * Use this method to register work which needs to be performed on module loading.
+ * For more about how to configure services, see
+ * {@link providers#provider-recipe Provider Recipe}.
+ */
+ config: config,
+
+ /**
+ * @ngdoc method
+ * @name angular.Module#run
+ * @module ng
+ * @param {Function} initializationFn Execute this function after injector creation.
+ * Useful for application initialization.
+ * @description
+ * Use this method to register work which should be performed when the injector is done
+ * loading all modules.
+ */
+ run: function(block) {
+ runBlocks.push(block);
+ return this;
+ }
+ };
+
+ if (configFn) {
+ config(configFn);
+ }
+
+ return moduleInstance;
+
+ /**
+ * @param {string} provider
+ * @param {string} method
+ * @param {String=} insertMethod
+ * @returns {angular.Module}
+ */
+ function invokeLater(provider, method, insertMethod, queue) {
+ if (!queue) queue = invokeQueue;
+ return function() {
+ queue[insertMethod || 'push']([provider, method, arguments]);
+ return moduleInstance;
+ };
+ }
+ });
+ };
+ });
+
+}
+
+/* global: toDebugString: true */
+
+function serializeObject(obj) {
+ var seen = [];
+
+ return JSON.stringify(obj, function(key, val) {
+ val = toJsonReplacer(key, val);
+ if (isObject(val)) {
+
+ if (seen.indexOf(val) >= 0) return '<>';
+
+ seen.push(val);
+ }
+ return val;
+ });
+}
+
+function toDebugString(obj) {
+ if (typeof obj === 'function') {
+ return obj.toString().replace(/ \{[\s\S]*$/, '');
+ } else if (typeof obj === 'undefined') {
+ return 'undefined';
+ } else if (typeof obj !== 'string') {
+ return serializeObject(obj);
+ }
+ return obj;
+}
+
+/* global angularModule: true,
+ version: true,
+
+ $LocaleProvider,
+ $CompileProvider,
+
+ htmlAnchorDirective,
+ inputDirective,
+ inputDirective,
+ formDirective,
+ scriptDirective,
+ selectDirective,
+ styleDirective,
+ optionDirective,
+ ngBindDirective,
+ ngBindHtmlDirective,
+ ngBindTemplateDirective,
+ ngClassDirective,
+ ngClassEvenDirective,
+ ngClassOddDirective,
+ ngCspDirective,
+ ngCloakDirective,
+ ngControllerDirective,
+ ngFormDirective,
+ ngHideDirective,
+ ngIfDirective,
+ ngIncludeDirective,
+ ngIncludeFillContentDirective,
+ ngInitDirective,
+ ngNonBindableDirective,
+ ngPluralizeDirective,
+ ngRepeatDirective,
+ ngShowDirective,
+ ngStyleDirective,
+ ngSwitchDirective,
+ ngSwitchWhenDirective,
+ ngSwitchDefaultDirective,
+ ngOptionsDirective,
+ ngTranscludeDirective,
+ ngModelDirective,
+ ngListDirective,
+ ngChangeDirective,
+ patternDirective,
+ patternDirective,
+ requiredDirective,
+ requiredDirective,
+ minlengthDirective,
+ minlengthDirective,
+ maxlengthDirective,
+ maxlengthDirective,
+ ngValueDirective,
+ ngModelOptionsDirective,
+ ngAttributeAliasDirectives,
+ ngEventDirectives,
+
+ $AnchorScrollProvider,
+ $AnimateProvider,
+ $BrowserProvider,
+ $CacheFactoryProvider,
+ $ControllerProvider,
+ $DocumentProvider,
+ $ExceptionHandlerProvider,
+ $FilterProvider,
+ $InterpolateProvider,
+ $IntervalProvider,
+ $HttpProvider,
+ $HttpBackendProvider,
+ $LocationProvider,
+ $LogProvider,
+ $ParseProvider,
+ $RootScopeProvider,
+ $QProvider,
+ $$QProvider,
+ $$SanitizeUriProvider,
+ $SceProvider,
+ $SceDelegateProvider,
+ $SnifferProvider,
+ $TemplateCacheProvider,
+ $TemplateRequestProvider,
+ $$TestabilityProvider,
+ $TimeoutProvider,
+ $$RAFProvider,
+ $$AsyncCallbackProvider,
+ $WindowProvider,
+ $$jqLiteProvider
+*/
+
+
+/**
+ * @ngdoc object
+ * @name angular.version
+ * @module ng
+ * @description
+ * An object that contains information about the current AngularJS version. This object has the
+ * following properties:
+ *
+ * - `full` – `{string}` – Full version string, such as "0.9.18".
+ * - `major` – `{number}` – Major version number, such as "0".
+ * - `minor` – `{number}` – Minor version number, such as "9".
+ * - `dot` – `{number}` – Dot version number, such as "18".
+ * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
+ */
+var version = {
+ full: '1.3.8', // all of these placeholder strings will be replaced by grunt's
+ major: 1, // package task
+ minor: 3,
+ dot: 8,
+ codeName: 'prophetic-narwhal'
+};
+
+
+function publishExternalAPI(angular) {
+ extend(angular, {
+ 'bootstrap': bootstrap,
+ 'copy': copy,
+ 'extend': extend,
+ 'equals': equals,
+ 'element': jqLite,
+ 'forEach': forEach,
+ 'injector': createInjector,
+ 'noop': noop,
+ 'bind': bind,
+ 'toJson': toJson,
+ 'fromJson': fromJson,
+ 'identity': identity,
+ 'isUndefined': isUndefined,
+ 'isDefined': isDefined,
+ 'isString': isString,
+ 'isFunction': isFunction,
+ 'isObject': isObject,
+ 'isNumber': isNumber,
+ 'isElement': isElement,
+ 'isArray': isArray,
+ 'version': version,
+ 'isDate': isDate,
+ 'lowercase': lowercase,
+ 'uppercase': uppercase,
+ 'callbacks': {counter: 0},
+ 'getTestability': getTestability,
+ '$$minErr': minErr,
+ '$$csp': csp,
+ 'reloadWithDebugInfo': reloadWithDebugInfo
+ });
+
+ angularModule = setupModuleLoader(window);
+ try {
+ angularModule('ngLocale');
+ } catch (e) {
+ angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
+ }
+
+ angularModule('ng', ['ngLocale'], ['$provide',
+ function ngModule($provide) {
+ // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
+ $provide.provider({
+ $$sanitizeUri: $$SanitizeUriProvider
+ });
+ $provide.provider('$compile', $CompileProvider).
+ directive({
+ a: htmlAnchorDirective,
+ input: inputDirective,
+ textarea: inputDirective,
+ form: formDirective,
+ script: scriptDirective,
+ select: selectDirective,
+ style: styleDirective,
+ option: optionDirective,
+ ngBind: ngBindDirective,
+ ngBindHtml: ngBindHtmlDirective,
+ ngBindTemplate: ngBindTemplateDirective,
+ ngClass: ngClassDirective,
+ ngClassEven: ngClassEvenDirective,
+ ngClassOdd: ngClassOddDirective,
+ ngCloak: ngCloakDirective,
+ ngController: ngControllerDirective,
+ ngForm: ngFormDirective,
+ ngHide: ngHideDirective,
+ ngIf: ngIfDirective,
+ ngInclude: ngIncludeDirective,
+ ngInit: ngInitDirective,
+ ngNonBindable: ngNonBindableDirective,
+ ngPluralize: ngPluralizeDirective,
+ ngRepeat: ngRepeatDirective,
+ ngShow: ngShowDirective,
+ ngStyle: ngStyleDirective,
+ ngSwitch: ngSwitchDirective,
+ ngSwitchWhen: ngSwitchWhenDirective,
+ ngSwitchDefault: ngSwitchDefaultDirective,
+ ngOptions: ngOptionsDirective,
+ ngTransclude: ngTranscludeDirective,
+ ngModel: ngModelDirective,
+ ngList: ngListDirective,
+ ngChange: ngChangeDirective,
+ pattern: patternDirective,
+ ngPattern: patternDirective,
+ required: requiredDirective,
+ ngRequired: requiredDirective,
+ minlength: minlengthDirective,
+ ngMinlength: minlengthDirective,
+ maxlength: maxlengthDirective,
+ ngMaxlength: maxlengthDirective,
+ ngValue: ngValueDirective,
+ ngModelOptions: ngModelOptionsDirective
+ }).
+ directive({
+ ngInclude: ngIncludeFillContentDirective
+ }).
+ directive(ngAttributeAliasDirectives).
+ directive(ngEventDirectives);
+ $provide.provider({
+ $anchorScroll: $AnchorScrollProvider,
+ $animate: $AnimateProvider,
+ $browser: $BrowserProvider,
+ $cacheFactory: $CacheFactoryProvider,
+ $controller: $ControllerProvider,
+ $document: $DocumentProvider,
+ $exceptionHandler: $ExceptionHandlerProvider,
+ $filter: $FilterProvider,
+ $interpolate: $InterpolateProvider,
+ $interval: $IntervalProvider,
+ $http: $HttpProvider,
+ $httpBackend: $HttpBackendProvider,
+ $location: $LocationProvider,
+ $log: $LogProvider,
+ $parse: $ParseProvider,
+ $rootScope: $RootScopeProvider,
+ $q: $QProvider,
+ $$q: $$QProvider,
+ $sce: $SceProvider,
+ $sceDelegate: $SceDelegateProvider,
+ $sniffer: $SnifferProvider,
+ $templateCache: $TemplateCacheProvider,
+ $templateRequest: $TemplateRequestProvider,
+ $$testability: $$TestabilityProvider,
+ $timeout: $TimeoutProvider,
+ $window: $WindowProvider,
+ $$rAF: $$RAFProvider,
+ $$asyncCallback: $$AsyncCallbackProvider,
+ $$jqLite: $$jqLiteProvider
+ });
+ }
+ ]);
+}
+
+/* global JQLitePrototype: true,
+ addEventListenerFn: true,
+ removeEventListenerFn: true,
+ BOOLEAN_ATTR: true,
+ ALIASED_ATTR: true,
+*/
+
+//////////////////////////////////
+//JQLite
+//////////////////////////////////
+
+/**
+ * @ngdoc function
+ * @name angular.element
+ * @module ng
+ * @kind function
+ *
+ * @description
+ * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
+ *
+ * If jQuery is available, `angular.element` is an alias for the
+ * [jQuery](http://api.jquery.com/jQuery/) function. If jQuery is not available, `angular.element`
+ * delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite."
+ *
+ *
jqLite is a tiny, API-compatible subset of jQuery that allows
+ * Angular to manipulate the DOM in a cross-browser compatible way. **jqLite** implements only the most
+ * commonly needed functionality with the goal of having a very small footprint.
+ *
+ * To use jQuery, simply load it before `DOMContentLoaded` event fired.
+ *
+ *
**Note:** all element references in Angular are always wrapped with jQuery or
+ * jqLite; they are never raw DOM references.
+ *
+ * ## Angular's jqLite
+ * jqLite provides only the following jQuery methods:
+ *
+ * - [`addClass()`](http://api.jquery.com/addClass/)
+ * - [`after()`](http://api.jquery.com/after/)
+ * - [`append()`](http://api.jquery.com/append/)
+ * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters
+ * - [`bind()`](http://api.jquery.com/bind/) - Does not support namespaces, selectors or eventData
+ * - [`children()`](http://api.jquery.com/children/) - Does not support selectors
+ * - [`clone()`](http://api.jquery.com/clone/)
+ * - [`contents()`](http://api.jquery.com/contents/)
+ * - [`css()`](http://api.jquery.com/css/) - Only retrieves inline-styles, does not call `getComputedStyle()`
+ * - [`data()`](http://api.jquery.com/data/)
+ * - [`detach()`](http://api.jquery.com/detach/)
+ * - [`empty()`](http://api.jquery.com/empty/)
+ * - [`eq()`](http://api.jquery.com/eq/)
+ * - [`find()`](http://api.jquery.com/find/) - Limited to lookups by tag name
+ * - [`hasClass()`](http://api.jquery.com/hasClass/)
+ * - [`html()`](http://api.jquery.com/html/)
+ * - [`next()`](http://api.jquery.com/next/) - Does not support selectors
+ * - [`on()`](http://api.jquery.com/on/) - Does not support namespaces, selectors or eventData
+ * - [`off()`](http://api.jquery.com/off/) - Does not support namespaces or selectors
+ * - [`one()`](http://api.jquery.com/one/) - Does not support namespaces or selectors
+ * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors
+ * - [`prepend()`](http://api.jquery.com/prepend/)
+ * - [`prop()`](http://api.jquery.com/prop/)
+ * - [`ready()`](http://api.jquery.com/ready/)
+ * - [`remove()`](http://api.jquery.com/remove/)
+ * - [`removeAttr()`](http://api.jquery.com/removeAttr/)
+ * - [`removeClass()`](http://api.jquery.com/removeClass/)
+ * - [`removeData()`](http://api.jquery.com/removeData/)
+ * - [`replaceWith()`](http://api.jquery.com/replaceWith/)
+ * - [`text()`](http://api.jquery.com/text/)
+ * - [`toggleClass()`](http://api.jquery.com/toggleClass/)
+ * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers.
+ * - [`unbind()`](http://api.jquery.com/unbind/) - Does not support namespaces
+ * - [`val()`](http://api.jquery.com/val/)
+ * - [`wrap()`](http://api.jquery.com/wrap/)
+ *
+ * ## jQuery/jqLite Extras
+ * Angular also provides the following additional methods and events to both jQuery and jqLite:
+ *
+ * ### Events
+ * - `$destroy` - AngularJS intercepts all jqLite/jQuery's DOM destruction apis and fires this event
+ * on all DOM nodes being removed. This can be used to clean up any 3rd party bindings to the DOM
+ * element before it is removed.
+ *
+ * ### Methods
+ * - `controller(name)` - retrieves the controller of the current element or its parent. By default
+ * retrieves controller associated with the `ngController` directive. If `name` is provided as
+ * camelCase directive name, then the controller for this directive will be retrieved (e.g.
+ * `'ngModel'`).
+ * - `injector()` - retrieves the injector of the current element or its parent.
+ * - `scope()` - retrieves the {@link ng.$rootScope.Scope scope} of the current
+ * element or its parent. Requires {@link guide/production#disabling-debug-data Debug Data} to
+ * be enabled.
+ * - `isolateScope()` - retrieves an isolate {@link ng.$rootScope.Scope scope} if one is attached directly to the
+ * current element. This getter should be used only on elements that contain a directive which starts a new isolate
+ * scope. Calling `scope()` on this element always returns the original non-isolate scope.
+ * Requires {@link guide/production#disabling-debug-data Debug Data} to be enabled.
+ * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
+ * parent element is reached.
+ *
+ * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
+ * @returns {Object} jQuery object.
+ */
+
+JQLite.expando = 'ng339';
+
+var jqCache = JQLite.cache = {},
+ jqId = 1,
+ addEventListenerFn = function(element, type, fn) {
+ element.addEventListener(type, fn, false);
+ },
+ removeEventListenerFn = function(element, type, fn) {
+ element.removeEventListener(type, fn, false);
+ };
+
+/*
+ * !!! This is an undocumented "private" function !!!
+ */
+JQLite._data = function(node) {
+ //jQuery always returns an object on cache miss
+ return this.cache[node[this.expando]] || {};
+};
+
+function jqNextId() { return ++jqId; }
+
+
+var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
+var MOZ_HACK_REGEXP = /^moz([A-Z])/;
+var MOUSE_EVENT_MAP= { mouseleave: "mouseout", mouseenter: "mouseover"};
+var jqLiteMinErr = minErr('jqLite');
+
+/**
+ * Converts snake_case to camelCase.
+ * Also there is special case for Moz prefix starting with upper case letter.
+ * @param name Name to normalize
+ */
+function camelCase(name) {
+ return name.
+ replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
+ return offset ? letter.toUpperCase() : letter;
+ }).
+ replace(MOZ_HACK_REGEXP, 'Moz$1');
+}
+
+var SINGLE_TAG_REGEXP = /^<(\w+)\s*\/?>(?:<\/\1>|)$/;
+var HTML_REGEXP = /<|?\w+;/;
+var TAG_NAME_REGEXP = /<([\w:]+)/;
+var XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi;
+
+var wrapMap = {
+ 'option': [1, ''],
+
+ 'thead': [1, '
', '
'],
+ 'col': [2, '
', '
'],
+ 'tr': [2, '
', '
'],
+ 'td': [3, '
', '
'],
+ '_default': [0, "", ""]
+};
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function jqLiteIsTextNode(html) {
+ return !HTML_REGEXP.test(html);
+}
+
+function jqLiteAcceptsData(node) {
+ // The window object can accept data but has no nodeType
+ // Otherwise we are only interested in elements (1) and documents (9)
+ var nodeType = node.nodeType;
+ return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT;
+}
+
+function jqLiteBuildFragment(html, context) {
+ var tmp, tag, wrap,
+ fragment = context.createDocumentFragment(),
+ nodes = [], i;
+
+ if (jqLiteIsTextNode(html)) {
+ // Convert non-html into a text node
+ nodes.push(context.createTextNode(html));
+ } else {
+ // Convert html into DOM nodes
+ tmp = tmp || fragment.appendChild(context.createElement("div"));
+ tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase();
+ wrap = wrapMap[tag] || wrapMap._default;
+ tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, "<$1>$2>") + wrap[2];
+
+ // Descend through wrappers to the right content
+ i = wrap[0];
+ while (i--) {
+ tmp = tmp.lastChild;
+ }
+
+ nodes = concat(nodes, tmp.childNodes);
+
+ tmp = fragment.firstChild;
+ tmp.textContent = "";
+ }
+
+ // Remove wrapper from fragment
+ fragment.textContent = "";
+ fragment.innerHTML = ""; // Clear inner HTML
+ forEach(nodes, function(node) {
+ fragment.appendChild(node);
+ });
+
+ return fragment;
+}
+
+function jqLiteParseHTML(html, context) {
+ context = context || document;
+ var parsed;
+
+ if ((parsed = SINGLE_TAG_REGEXP.exec(html))) {
+ return [context.createElement(parsed[1])];
+ }
+
+ if ((parsed = jqLiteBuildFragment(html, context))) {
+ return parsed.childNodes;
+ }
+
+ return [];
+}
+
+/////////////////////////////////////////////
+function JQLite(element) {
+ if (element instanceof JQLite) {
+ return element;
+ }
+
+ var argIsString;
+
+ if (isString(element)) {
+ element = trim(element);
+ argIsString = true;
+ }
+ if (!(this instanceof JQLite)) {
+ if (argIsString && element.charAt(0) != '<') {
+ throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
+ }
+ return new JQLite(element);
+ }
+
+ if (argIsString) {
+ jqLiteAddNodes(this, jqLiteParseHTML(element));
+ } else {
+ jqLiteAddNodes(this, element);
+ }
+}
+
+function jqLiteClone(element) {
+ return element.cloneNode(true);
+}
+
+function jqLiteDealoc(element, onlyDescendants) {
+ if (!onlyDescendants) jqLiteRemoveData(element);
+
+ if (element.querySelectorAll) {
+ var descendants = element.querySelectorAll('*');
+ for (var i = 0, l = descendants.length; i < l; i++) {
+ jqLiteRemoveData(descendants[i]);
+ }
+ }
+}
+
+function jqLiteOff(element, type, fn, unsupported) {
+ if (isDefined(unsupported)) throw jqLiteMinErr('offargs', 'jqLite#off() does not support the `selector` argument');
+
+ var expandoStore = jqLiteExpandoStore(element);
+ var events = expandoStore && expandoStore.events;
+ var handle = expandoStore && expandoStore.handle;
+
+ if (!handle) return; //no listeners registered
+
+ if (!type) {
+ for (type in events) {
+ if (type !== '$destroy') {
+ removeEventListenerFn(element, type, handle);
+ }
+ delete events[type];
+ }
+ } else {
+ forEach(type.split(' '), function(type) {
+ if (isDefined(fn)) {
+ var listenerFns = events[type];
+ arrayRemove(listenerFns || [], fn);
+ if (listenerFns && listenerFns.length > 0) {
+ return;
+ }
+ }
+
+ removeEventListenerFn(element, type, handle);
+ delete events[type];
+ });
+ }
+}
+
+function jqLiteRemoveData(element, name) {
+ var expandoId = element.ng339;
+ var expandoStore = expandoId && jqCache[expandoId];
+
+ if (expandoStore) {
+ if (name) {
+ delete expandoStore.data[name];
+ return;
+ }
+
+ if (expandoStore.handle) {
+ if (expandoStore.events.$destroy) {
+ expandoStore.handle({}, '$destroy');
+ }
+ jqLiteOff(element);
+ }
+ delete jqCache[expandoId];
+ element.ng339 = undefined; // don't delete DOM expandos. IE and Chrome don't like it
+ }
+}
+
+
+function jqLiteExpandoStore(element, createIfNecessary) {
+ var expandoId = element.ng339,
+ expandoStore = expandoId && jqCache[expandoId];
+
+ if (createIfNecessary && !expandoStore) {
+ element.ng339 = expandoId = jqNextId();
+ expandoStore = jqCache[expandoId] = {events: {}, data: {}, handle: undefined};
+ }
+
+ return expandoStore;
+}
+
+
+function jqLiteData(element, key, value) {
+ if (jqLiteAcceptsData(element)) {
+
+ var isSimpleSetter = isDefined(value);
+ var isSimpleGetter = !isSimpleSetter && key && !isObject(key);
+ var massGetter = !key;
+ var expandoStore = jqLiteExpandoStore(element, !isSimpleGetter);
+ var data = expandoStore && expandoStore.data;
+
+ if (isSimpleSetter) { // data('key', value)
+ data[key] = value;
+ } else {
+ if (massGetter) { // data()
+ return data;
+ } else {
+ if (isSimpleGetter) { // data('key')
+ // don't force creation of expandoStore if it doesn't exist yet
+ return data && data[key];
+ } else { // mass-setter: data({key1: val1, key2: val2})
+ extend(data, key);
+ }
+ }
+ }
+ }
+}
+
+function jqLiteHasClass(element, selector) {
+ if (!element.getAttribute) return false;
+ return ((" " + (element.getAttribute('class') || '') + " ").replace(/[\n\t]/g, " ").
+ indexOf(" " + selector + " ") > -1);
+}
+
+function jqLiteRemoveClass(element, cssClasses) {
+ if (cssClasses && element.setAttribute) {
+ forEach(cssClasses.split(' '), function(cssClass) {
+ element.setAttribute('class', trim(
+ (" " + (element.getAttribute('class') || '') + " ")
+ .replace(/[\n\t]/g, " ")
+ .replace(" " + trim(cssClass) + " ", " "))
+ );
+ });
+ }
+}
+
+function jqLiteAddClass(element, cssClasses) {
+ if (cssClasses && element.setAttribute) {
+ var existingClasses = (' ' + (element.getAttribute('class') || '') + ' ')
+ .replace(/[\n\t]/g, " ");
+
+ forEach(cssClasses.split(' '), function(cssClass) {
+ cssClass = trim(cssClass);
+ if (existingClasses.indexOf(' ' + cssClass + ' ') === -1) {
+ existingClasses += cssClass + ' ';
+ }
+ });
+
+ element.setAttribute('class', trim(existingClasses));
+ }
+}
+
+
+function jqLiteAddNodes(root, elements) {
+ // THIS CODE IS VERY HOT. Don't make changes without benchmarking.
+
+ if (elements) {
+
+ // if a Node (the most common case)
+ if (elements.nodeType) {
+ root[root.length++] = elements;
+ } else {
+ var length = elements.length;
+
+ // if an Array or NodeList and not a Window
+ if (typeof length === 'number' && elements.window !== elements) {
+ if (length) {
+ for (var i = 0; i < length; i++) {
+ root[root.length++] = elements[i];
+ }
+ }
+ } else {
+ root[root.length++] = elements;
+ }
+ }
+ }
+}
+
+
+function jqLiteController(element, name) {
+ return jqLiteInheritedData(element, '$' + (name || 'ngController') + 'Controller');
+}
+
+function jqLiteInheritedData(element, name, value) {
+ // if element is the document object work with the html element instead
+ // this makes $(document).scope() possible
+ if (element.nodeType == NODE_TYPE_DOCUMENT) {
+ element = element.documentElement;
+ }
+ var names = isArray(name) ? name : [name];
+
+ while (element) {
+ for (var i = 0, ii = names.length; i < ii; i++) {
+ if ((value = jqLite.data(element, names[i])) !== undefined) return value;
+ }
+
+ // If dealing with a document fragment node with a host element, and no parent, use the host
+ // element as the parent. This enables directives within a Shadow DOM or polyfilled Shadow DOM
+ // to lookup parent controllers.
+ element = element.parentNode || (element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host);
+ }
+}
+
+function jqLiteEmpty(element) {
+ jqLiteDealoc(element, true);
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+}
+
+function jqLiteRemove(element, keepData) {
+ if (!keepData) jqLiteDealoc(element);
+ var parent = element.parentNode;
+ if (parent) parent.removeChild(element);
+}
+
+
+function jqLiteDocumentLoaded(action, win) {
+ win = win || window;
+ if (win.document.readyState === 'complete') {
+ // Force the action to be run async for consistent behaviour
+ // from the action's point of view
+ // i.e. it will definitely not be in a $apply
+ win.setTimeout(action);
+ } else {
+ // No need to unbind this handler as load is only ever called once
+ jqLite(win).on('load', action);
+ }
+}
+
+//////////////////////////////////////////
+// Functions which are declared directly.
+//////////////////////////////////////////
+var JQLitePrototype = JQLite.prototype = {
+ ready: function(fn) {
+ var fired = false;
+
+ function trigger() {
+ if (fired) return;
+ fired = true;
+ fn();
+ }
+
+ // check if document is already loaded
+ if (document.readyState === 'complete') {
+ setTimeout(trigger);
+ } else {
+ this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
+ // we can not use jqLite since we are not done loading and jQuery could be loaded later.
+ // jshint -W064
+ JQLite(window).on('load', trigger); // fallback to window.onload for others
+ // jshint +W064
+ }
+ },
+ toString: function() {
+ var value = [];
+ forEach(this, function(e) { value.push('' + e);});
+ return '[' + value.join(', ') + ']';
+ },
+
+ eq: function(index) {
+ return (index >= 0) ? jqLite(this[index]) : jqLite(this[this.length + index]);
+ },
+
+ length: 0,
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+//////////////////////////////////////////
+// Functions iterating getter/setters.
+// these functions return self on setter and
+// value on get.
+//////////////////////////////////////////
+var BOOLEAN_ATTR = {};
+forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','), function(value) {
+ BOOLEAN_ATTR[lowercase(value)] = value;
+});
+var BOOLEAN_ELEMENTS = {};
+forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
+ BOOLEAN_ELEMENTS[value] = true;
+});
+var ALIASED_ATTR = {
+ 'ngMinlength': 'minlength',
+ 'ngMaxlength': 'maxlength',
+ 'ngMin': 'min',
+ 'ngMax': 'max',
+ 'ngPattern': 'pattern'
+};
+
+function getBooleanAttrName(element, name) {
+ // check dom last since we will most likely fail on name
+ var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
+
+ // booleanAttr is here twice to minimize DOM access
+ return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
+}
+
+function getAliasedAttrName(element, name) {
+ var nodeName = element.nodeName;
+ return (nodeName === 'INPUT' || nodeName === 'TEXTAREA') && ALIASED_ATTR[name];
+}
+
+forEach({
+ data: jqLiteData,
+ removeData: jqLiteRemoveData
+}, function(fn, name) {
+ JQLite[name] = fn;
+});
+
+forEach({
+ data: jqLiteData,
+ inheritedData: jqLiteInheritedData,
+
+ scope: function(element) {
+ // Can't use jqLiteData here directly so we stay compatible with jQuery!
+ return jqLite.data(element, '$scope') || jqLiteInheritedData(element.parentNode || element, ['$isolateScope', '$scope']);
+ },
+
+ isolateScope: function(element) {
+ // Can't use jqLiteData here directly so we stay compatible with jQuery!
+ return jqLite.data(element, '$isolateScope') || jqLite.data(element, '$isolateScopeNoTemplate');
+ },
+
+ controller: jqLiteController,
+
+ injector: function(element) {
+ return jqLiteInheritedData(element, '$injector');
+ },
+
+ removeAttr: function(element, name) {
+ element.removeAttribute(name);
+ },
+
+ hasClass: jqLiteHasClass,
+
+ css: function(element, name, value) {
+ name = camelCase(name);
+
+ if (isDefined(value)) {
+ element.style[name] = value;
+ } else {
+ return element.style[name];
+ }
+ },
+
+ attr: function(element, name, value) {
+ var lowercasedName = lowercase(name);
+ if (BOOLEAN_ATTR[lowercasedName]) {
+ if (isDefined(value)) {
+ if (!!value) {
+ element[name] = true;
+ element.setAttribute(name, lowercasedName);
+ } else {
+ element[name] = false;
+ element.removeAttribute(lowercasedName);
+ }
+ } else {
+ return (element[name] ||
+ (element.attributes.getNamedItem(name) || noop).specified)
+ ? lowercasedName
+ : undefined;
+ }
+ } else if (isDefined(value)) {
+ element.setAttribute(name, value);
+ } else if (element.getAttribute) {
+ // the extra argument "2" is to get the right thing for a.href in IE, see jQuery code
+ // some elements (e.g. Document) don't have get attribute, so return undefined
+ var ret = element.getAttribute(name, 2);
+ // normalize non-existing attributes to undefined (as jQuery)
+ return ret === null ? undefined : ret;
+ }
+ },
+
+ prop: function(element, name, value) {
+ if (isDefined(value)) {
+ element[name] = value;
+ } else {
+ return element[name];
+ }
+ },
+
+ text: (function() {
+ getText.$dv = '';
+ return getText;
+
+ function getText(element, value) {
+ if (isUndefined(value)) {
+ var nodeType = element.nodeType;
+ return (nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT) ? element.textContent : '';
+ }
+ element.textContent = value;
+ }
+ })(),
+
+ val: function(element, value) {
+ if (isUndefined(value)) {
+ if (element.multiple && nodeName_(element) === 'select') {
+ var result = [];
+ forEach(element.options, function(option) {
+ if (option.selected) {
+ result.push(option.value || option.text);
+ }
+ });
+ return result.length === 0 ? null : result;
+ }
+ return element.value;
+ }
+ element.value = value;
+ },
+
+ html: function(element, value) {
+ if (isUndefined(value)) {
+ return element.innerHTML;
+ }
+ jqLiteDealoc(element, true);
+ element.innerHTML = value;
+ },
+
+ empty: jqLiteEmpty
+}, function(fn, name) {
+ /**
+ * Properties: writes return selection, reads return first value
+ */
+ JQLite.prototype[name] = function(arg1, arg2) {
+ var i, key;
+ var nodeCount = this.length;
+
+ // jqLiteHasClass has only two arguments, but is a getter-only fn, so we need to special-case it
+ // in a way that survives minification.
+ // jqLiteEmpty takes no arguments but is a setter.
+ if (fn !== jqLiteEmpty &&
+ (((fn.length == 2 && (fn !== jqLiteHasClass && fn !== jqLiteController)) ? arg1 : arg2) === undefined)) {
+ if (isObject(arg1)) {
+
+ // we are a write, but the object properties are the key/values
+ for (i = 0; i < nodeCount; i++) {
+ if (fn === jqLiteData) {
+ // data() takes the whole object in jQuery
+ fn(this[i], arg1);
+ } else {
+ for (key in arg1) {
+ fn(this[i], key, arg1[key]);
+ }
+ }
+ }
+ // return self for chaining
+ return this;
+ } else {
+ // we are a read, so read the first child.
+ // TODO: do we still need this?
+ var value = fn.$dv;
+ // Only if we have $dv do we iterate over all, otherwise it is just the first element.
+ var jj = (value === undefined) ? Math.min(nodeCount, 1) : nodeCount;
+ for (var j = 0; j < jj; j++) {
+ var nodeValue = fn(this[j], arg1, arg2);
+ value = value ? value + nodeValue : nodeValue;
+ }
+ return value;
+ }
+ } else {
+ // we are a write, so apply to all children
+ for (i = 0; i < nodeCount; i++) {
+ fn(this[i], arg1, arg2);
+ }
+ // return self for chaining
+ return this;
+ }
+ };
+});
+
+function createEventHandler(element, events) {
+ var eventHandler = function(event, type) {
+ // jQuery specific api
+ event.isDefaultPrevented = function() {
+ return event.defaultPrevented;
+ };
+
+ var eventFns = events[type || event.type];
+ var eventFnsLength = eventFns ? eventFns.length : 0;
+
+ if (!eventFnsLength) return;
+
+ if (isUndefined(event.immediatePropagationStopped)) {
+ var originalStopImmediatePropagation = event.stopImmediatePropagation;
+ event.stopImmediatePropagation = function() {
+ event.immediatePropagationStopped = true;
+
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+
+ if (originalStopImmediatePropagation) {
+ originalStopImmediatePropagation.call(event);
+ }
+ };
+ }
+
+ event.isImmediatePropagationStopped = function() {
+ return event.immediatePropagationStopped === true;
+ };
+
+ // Copy event handlers in case event handlers array is modified during execution.
+ if ((eventFnsLength > 1)) {
+ eventFns = shallowCopy(eventFns);
+ }
+
+ for (var i = 0; i < eventFnsLength; i++) {
+ if (!event.isImmediatePropagationStopped()) {
+ eventFns[i].call(element, event);
+ }
+ }
+ };
+
+ // TODO: this is a hack for angularMocks/clearDataCache that makes it possible to deregister all
+ // events on `element`
+ eventHandler.elem = element;
+ return eventHandler;
+}
+
+//////////////////////////////////////////
+// Functions iterating traversal.
+// These functions chain results into a single
+// selector.
+//////////////////////////////////////////
+forEach({
+ removeData: jqLiteRemoveData,
+
+ on: function jqLiteOn(element, type, fn, unsupported) {
+ if (isDefined(unsupported)) throw jqLiteMinErr('onargs', 'jqLite#on() does not support the `selector` or `eventData` parameters');
+
+ // Do not add event handlers to non-elements because they will not be cleaned up.
+ if (!jqLiteAcceptsData(element)) {
+ return;
+ }
+
+ var expandoStore = jqLiteExpandoStore(element, true);
+ var events = expandoStore.events;
+ var handle = expandoStore.handle;
+
+ if (!handle) {
+ handle = expandoStore.handle = createEventHandler(element, events);
+ }
+
+ // http://jsperf.com/string-indexof-vs-split
+ var types = type.indexOf(' ') >= 0 ? type.split(' ') : [type];
+ var i = types.length;
+
+ while (i--) {
+ type = types[i];
+ var eventFns = events[type];
+
+ if (!eventFns) {
+ events[type] = [];
+
+ if (type === 'mouseenter' || type === 'mouseleave') {
+ // Refer to jQuery's implementation of mouseenter & mouseleave
+ // Read about mouseenter and mouseleave:
+ // http://www.quirksmode.org/js/events_mouse.html#link8
+
+ jqLiteOn(element, MOUSE_EVENT_MAP[type], function(event) {
+ var target = this, related = event.relatedTarget;
+ // For mousenter/leave call the handler if related is outside the target.
+ // NB: No relatedTarget if the mouse left/entered the browser window
+ if (!related || (related !== target && !target.contains(related))) {
+ handle(event, type);
+ }
+ });
+
+ } else {
+ if (type !== '$destroy') {
+ addEventListenerFn(element, type, handle);
+ }
+ }
+ eventFns = events[type];
+ }
+ eventFns.push(fn);
+ }
+ },
+
+ off: jqLiteOff,
+
+ one: function(element, type, fn) {
+ element = jqLite(element);
+
+ //add the listener twice so that when it is called
+ //you can remove the original function and still be
+ //able to call element.off(ev, fn) normally
+ element.on(type, function onFn() {
+ element.off(type, fn);
+ element.off(type, onFn);
+ });
+ element.on(type, fn);
+ },
+
+ replaceWith: function(element, replaceNode) {
+ var index, parent = element.parentNode;
+ jqLiteDealoc(element);
+ forEach(new JQLite(replaceNode), function(node) {
+ if (index) {
+ parent.insertBefore(node, index.nextSibling);
+ } else {
+ parent.replaceChild(node, element);
+ }
+ index = node;
+ });
+ },
+
+ children: function(element) {
+ var children = [];
+ forEach(element.childNodes, function(element) {
+ if (element.nodeType === NODE_TYPE_ELEMENT)
+ children.push(element);
+ });
+ return children;
+ },
+
+ contents: function(element) {
+ return element.contentDocument || element.childNodes || [];
+ },
+
+ append: function(element, node) {
+ var nodeType = element.nodeType;
+ if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return;
+
+ node = new JQLite(node);
+
+ for (var i = 0, ii = node.length; i < ii; i++) {
+ var child = node[i];
+ element.appendChild(child);
+ }
+ },
+
+ prepend: function(element, node) {
+ if (element.nodeType === NODE_TYPE_ELEMENT) {
+ var index = element.firstChild;
+ forEach(new JQLite(node), function(child) {
+ element.insertBefore(child, index);
+ });
+ }
+ },
+
+ wrap: function(element, wrapNode) {
+ wrapNode = jqLite(wrapNode).eq(0).clone()[0];
+ var parent = element.parentNode;
+ if (parent) {
+ parent.replaceChild(wrapNode, element);
+ }
+ wrapNode.appendChild(element);
+ },
+
+ remove: jqLiteRemove,
+
+ detach: function(element) {
+ jqLiteRemove(element, true);
+ },
+
+ after: function(element, newElement) {
+ var index = element, parent = element.parentNode;
+ newElement = new JQLite(newElement);
+
+ for (var i = 0, ii = newElement.length; i < ii; i++) {
+ var node = newElement[i];
+ parent.insertBefore(node, index.nextSibling);
+ index = node;
+ }
+ },
+
+ addClass: jqLiteAddClass,
+ removeClass: jqLiteRemoveClass,
+
+ toggleClass: function(element, selector, condition) {
+ if (selector) {
+ forEach(selector.split(' '), function(className) {
+ var classCondition = condition;
+ if (isUndefined(classCondition)) {
+ classCondition = !jqLiteHasClass(element, className);
+ }
+ (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className);
+ });
+ }
+ },
+
+ parent: function(element) {
+ var parent = element.parentNode;
+ return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null;
+ },
+
+ next: function(element) {
+ return element.nextElementSibling;
+ },
+
+ find: function(element, selector) {
+ if (element.getElementsByTagName) {
+ return element.getElementsByTagName(selector);
+ } else {
+ return [];
+ }
+ },
+
+ clone: jqLiteClone,
+
+ triggerHandler: function(element, event, extraParameters) {
+
+ var dummyEvent, eventFnsCopy, handlerArgs;
+ var eventName = event.type || event;
+ var expandoStore = jqLiteExpandoStore(element);
+ var events = expandoStore && expandoStore.events;
+ var eventFns = events && events[eventName];
+
+ if (eventFns) {
+ // Create a dummy event to pass to the handlers
+ dummyEvent = {
+ preventDefault: function() { this.defaultPrevented = true; },
+ isDefaultPrevented: function() { return this.defaultPrevented === true; },
+ stopImmediatePropagation: function() { this.immediatePropagationStopped = true; },
+ isImmediatePropagationStopped: function() { return this.immediatePropagationStopped === true; },
+ stopPropagation: noop,
+ type: eventName,
+ target: element
+ };
+
+ // If a custom event was provided then extend our dummy event with it
+ if (event.type) {
+ dummyEvent = extend(dummyEvent, event);
+ }
+
+ // Copy event handlers in case event handlers array is modified during execution.
+ eventFnsCopy = shallowCopy(eventFns);
+ handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent];
+
+ forEach(eventFnsCopy, function(fn) {
+ if (!dummyEvent.isImmediatePropagationStopped()) {
+ fn.apply(element, handlerArgs);
+ }
+ });
+ }
+ }
+}, function(fn, name) {
+ /**
+ * chaining functions
+ */
+ JQLite.prototype[name] = function(arg1, arg2, arg3) {
+ var value;
+
+ for (var i = 0, ii = this.length; i < ii; i++) {
+ if (isUndefined(value)) {
+ value = fn(this[i], arg1, arg2, arg3);
+ if (isDefined(value)) {
+ // any function which returns a value needs to be wrapped
+ value = jqLite(value);
+ }
+ } else {
+ jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3));
+ }
+ }
+ return isDefined(value) ? value : this;
+ };
+
+ // bind legacy bind/unbind to on/off
+ JQLite.prototype.bind = JQLite.prototype.on;
+ JQLite.prototype.unbind = JQLite.prototype.off;
+});
+
+
+// Provider for private $$jqLite service
+function $$jqLiteProvider() {
+ this.$get = function $$jqLite() {
+ return extend(JQLite, {
+ hasClass: function(node, classes) {
+ if (node.attr) node = node[0];
+ return jqLiteHasClass(node, classes);
+ },
+ addClass: function(node, classes) {
+ if (node.attr) node = node[0];
+ return jqLiteAddClass(node, classes);
+ },
+ removeClass: function(node, classes) {
+ if (node.attr) node = node[0];
+ return jqLiteRemoveClass(node, classes);
+ }
+ });
+ };
+}
+
+/**
+ * Computes a hash of an 'obj'.
+ * Hash of a:
+ * string is string
+ * number is number as string
+ * object is either result of calling $$hashKey function on the object or uniquely generated id,
+ * that is also assigned to the $$hashKey property of the object.
+ *
+ * @param obj
+ * @returns {string} hash string such that the same input will have the same hash string.
+ * The resulting string key is in 'type:hashKey' format.
+ */
+function hashKey(obj, nextUidFn) {
+ var key = obj && obj.$$hashKey;
+
+ if (key) {
+ if (typeof key === 'function') {
+ key = obj.$$hashKey();
+ }
+ return key;
+ }
+
+ var objType = typeof obj;
+ if (objType == 'function' || (objType == 'object' && obj !== null)) {
+ key = obj.$$hashKey = objType + ':' + (nextUidFn || nextUid)();
+ } else {
+ key = objType + ':' + obj;
+ }
+
+ return key;
+}
+
+/**
+ * HashMap which can use objects as keys
+ */
+function HashMap(array, isolatedUid) {
+ if (isolatedUid) {
+ var uid = 0;
+ this.nextUid = function() {
+ return ++uid;
+ };
+ }
+ forEach(array, this.put, this);
+}
+HashMap.prototype = {
+ /**
+ * Store key value pair
+ * @param key key to store can be any type
+ * @param value value to store can be any type
+ */
+ put: function(key, value) {
+ this[hashKey(key, this.nextUid)] = value;
+ },
+
+ /**
+ * @param key
+ * @returns {Object} the value for the key
+ */
+ get: function(key) {
+ return this[hashKey(key, this.nextUid)];
+ },
+
+ /**
+ * Remove the key/value pair
+ * @param key
+ */
+ remove: function(key) {
+ var value = this[key = hashKey(key, this.nextUid)];
+ delete this[key];
+ return value;
+ }
+};
+
+/**
+ * @ngdoc function
+ * @module ng
+ * @name angular.injector
+ * @kind function
+ *
+ * @description
+ * Creates an injector object that can be used for retrieving services as well as for
+ * dependency injection (see {@link guide/di dependency injection}).
+ *
+ * @param {Array.} modules A list of module functions or their aliases. See
+ * {@link angular.module}. The `ng` module must be explicitly added.
+ * @param {boolean=} [strictDi=false] Whether the injector should be in strict mode, which
+ * disallows argument name annotation inference.
+ * @returns {injector} Injector object. See {@link auto.$injector $injector}.
+ *
+ * @example
+ * Typical usage
+ * ```js
+ * // create an injector
+ * var $injector = angular.injector(['ng']);
+ *
+ * // use the injector to kick off your application
+ * // use the type inference to auto inject arguments, or use implicit injection
+ * $injector.invoke(function($rootScope, $compile, $document) {
+ * $compile($document)($rootScope);
+ * $rootScope.$digest();
+ * });
+ * ```
+ *
+ * Sometimes you want to get access to the injector of a currently running Angular app
+ * from outside Angular. Perhaps, you want to inject and compile some markup after the
+ * application has been bootstrapped. You can do this using the extra `injector()` added
+ * to JQuery/jqLite elements. See {@link angular.element}.
+ *
+ * *This is fairly rare but could be the case if a third party library is injecting the
+ * markup.*
+ *
+ * In the following example a new block of HTML containing a `ng-controller`
+ * directive is added to the end of the document body by JQuery. We then compile and link
+ * it into the current AngularJS scope.
+ *
+ * ```js
+ * var $div = $('
{{content.label}}
');
+ * $(document.body).append($div);
+ *
+ * angular.element(document).injector().invoke(function($compile) {
+ * var scope = angular.element($div).scope();
+ * $compile($div)(scope);
+ * });
+ * ```
+ */
+
+
+/**
+ * @ngdoc module
+ * @name auto
+ * @description
+ *
+ * Implicit module which gets automatically added to each {@link auto.$injector $injector}.
+ */
+
+var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
+var FN_ARG_SPLIT = /,/;
+var FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
+var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
+var $injectorMinErr = minErr('$injector');
+
+function anonFn(fn) {
+ // For anonymous functions, showing at the very least the function signature can help in
+ // debugging.
+ var fnText = fn.toString().replace(STRIP_COMMENTS, ''),
+ args = fnText.match(FN_ARGS);
+ if (args) {
+ return 'function(' + (args[1] || '').replace(/[\s\r\n]+/, ' ') + ')';
+ }
+ return 'fn';
+}
+
+function annotate(fn, strictDi, name) {
+ var $inject,
+ fnText,
+ argDecl,
+ last;
+
+ if (typeof fn === 'function') {
+ if (!($inject = fn.$inject)) {
+ $inject = [];
+ if (fn.length) {
+ if (strictDi) {
+ if (!isString(name) || !name) {
+ name = fn.name || anonFn(fn);
+ }
+ throw $injectorMinErr('strictdi',
+ '{0} is not using explicit annotation and cannot be invoked in strict mode', name);
+ }
+ fnText = fn.toString().replace(STRIP_COMMENTS, '');
+ argDecl = fnText.match(FN_ARGS);
+ forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) {
+ arg.replace(FN_ARG, function(all, underscore, name) {
+ $inject.push(name);
+ });
+ });
+ }
+ fn.$inject = $inject;
+ }
+ } else if (isArray(fn)) {
+ last = fn.length - 1;
+ assertArgFn(fn[last], 'fn');
+ $inject = fn.slice(0, last);
+ } else {
+ assertArgFn(fn, 'fn', true);
+ }
+ return $inject;
+}
+
+///////////////////////////////////////
+
+/**
+ * @ngdoc service
+ * @name $injector
+ *
+ * @description
+ *
+ * `$injector` is used to retrieve object instances as defined by
+ * {@link auto.$provide provider}, instantiate types, invoke methods,
+ * and load modules.
+ *
+ * The following always holds true:
+ *
+ * ```js
+ * var $injector = angular.injector();
+ * expect($injector.get('$injector')).toBe($injector);
+ * expect($injector.invoke(function($injector) {
+ * return $injector;
+ * })).toBe($injector);
+ * ```
+ *
+ * # Injection Function Annotation
+ *
+ * JavaScript does not have annotations, and annotations are needed for dependency injection. The
+ * following are all valid ways of annotating function with injection arguments and are equivalent.
+ *
+ * ```js
+ * // inferred (only works if code not minified/obfuscated)
+ * $injector.invoke(function(serviceA){});
+ *
+ * // annotated
+ * function explicit(serviceA) {};
+ * explicit.$inject = ['serviceA'];
+ * $injector.invoke(explicit);
+ *
+ * // inline
+ * $injector.invoke(['serviceA', function(serviceA){}]);
+ * ```
+ *
+ * ## Inference
+ *
+ * In JavaScript calling `toString()` on a function returns the function definition. The definition
+ * can then be parsed and the function arguments can be extracted. This method of discovering
+ * annotations is disallowed when the injector is in strict mode.
+ * *NOTE:* This does not work with minification, and obfuscation tools since these tools change the
+ * argument names.
+ *
+ * ## `$inject` Annotation
+ * By adding an `$inject` property onto a function the injection parameters can be specified.
+ *
+ * ## Inline
+ * As an array of injection names, where the last item in the array is the function to call.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#get
+ *
+ * @description
+ * Return an instance of the service.
+ *
+ * @param {string} name The name of the instance to retrieve.
+ * @param {string} caller An optional string to provide the origin of the function call for error messages.
+ * @return {*} The instance.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#invoke
+ *
+ * @description
+ * Invoke the method and supply the method arguments from the `$injector`.
+ *
+ * @param {!Function} fn The function to invoke. Function parameters are injected according to the
+ * {@link guide/di $inject Annotation} rules.
+ * @param {Object=} self The `this` for the invoked method.
+ * @param {Object=} locals Optional object. If preset then any argument names are read from this
+ * object first, before the `$injector` is consulted.
+ * @returns {*} the value returned by the invoked `fn` function.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#has
+ *
+ * @description
+ * Allows the user to query if the particular service exists.
+ *
+ * @param {string} name Name of the service to query.
+ * @returns {boolean} `true` if injector has given service.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#instantiate
+ * @description
+ * Create a new instance of JS type. The method takes a constructor function, invokes the new
+ * operator, and supplies all of the arguments to the constructor function as specified by the
+ * constructor annotation.
+ *
+ * @param {Function} Type Annotated constructor function.
+ * @param {Object=} locals Optional object. If preset then any argument names are read from this
+ * object first, before the `$injector` is consulted.
+ * @returns {Object} new instance of `Type`.
+ */
+
+/**
+ * @ngdoc method
+ * @name $injector#annotate
+ *
+ * @description
+ * Returns an array of service names which the function is requesting for injection. This API is
+ * used by the injector to determine which services need to be injected into the function when the
+ * function is invoked. There are three ways in which the function can be annotated with the needed
+ * dependencies.
+ *
+ * # Argument names
+ *
+ * The simplest form is to extract the dependencies from the arguments of the function. This is done
+ * by converting the function into a string using `toString()` method and extracting the argument
+ * names.
+ * ```js
+ * // Given
+ * function MyController($scope, $route) {
+ * // ...
+ * }
+ *
+ * // Then
+ * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
+ * ```
+ *
+ * You can disallow this method by using strict injection mode.
+ *
+ * This method does not work with code minification / obfuscation. For this reason the following
+ * annotation strategies are supported.
+ *
+ * # The `$inject` property
+ *
+ * If a function has an `$inject` property and its value is an array of strings, then the strings
+ * represent names of services to be injected into the function.
+ * ```js
+ * // Given
+ * var MyController = function(obfuscatedScope, obfuscatedRoute) {
+ * // ...
+ * }
+ * // Define function dependencies
+ * MyController['$inject'] = ['$scope', '$route'];
+ *
+ * // Then
+ * expect(injector.annotate(MyController)).toEqual(['$scope', '$route']);
+ * ```
+ *
+ * # The array notation
+ *
+ * It is often desirable to inline Injected functions and that's when setting the `$inject` property
+ * is very inconvenient. In these situations using the array notation to specify the dependencies in
+ * a way that survives minification is a better choice:
+ *
+ * ```js
+ * // We wish to write this (not minification / obfuscation safe)
+ * injector.invoke(function($compile, $rootScope) {
+ * // ...
+ * });
+ *
+ * // We are forced to write break inlining
+ * var tmpFn = function(obfuscatedCompile, obfuscatedRootScope) {
+ * // ...
+ * };
+ * tmpFn.$inject = ['$compile', '$rootScope'];
+ * injector.invoke(tmpFn);
+ *
+ * // To better support inline function the inline annotation is supported
+ * injector.invoke(['$compile', '$rootScope', function(obfCompile, obfRootScope) {
+ * // ...
+ * }]);
+ *
+ * // Therefore
+ * expect(injector.annotate(
+ * ['$compile', '$rootScope', function(obfus_$compile, obfus_$rootScope) {}])
+ * ).toEqual(['$compile', '$rootScope']);
+ * ```
+ *
+ * @param {Function|Array.} fn Function for which dependent service names need to
+ * be retrieved as described above.
+ *
+ * @param {boolean=} [strictDi=false] Disallow argument name annotation inference.
+ *
+ * @returns {Array.} The names of the services which the function requires.
+ */
+
+
+
+
+/**
+ * @ngdoc service
+ * @name $provide
+ *
+ * @description
+ *
+ * The {@link auto.$provide $provide} service has a number of methods for registering components
+ * with the {@link auto.$injector $injector}. Many of these functions are also exposed on
+ * {@link angular.Module}.
+ *
+ * An Angular **service** is a singleton object created by a **service factory**. These **service
+ * factories** are functions which, in turn, are created by a **service provider**.
+ * The **service providers** are constructor functions. When instantiated they must contain a
+ * property called `$get`, which holds the **service factory** function.
+ *
+ * When you request a service, the {@link auto.$injector $injector} is responsible for finding the
+ * correct **service provider**, instantiating it and then calling its `$get` **service factory**
+ * function to get the instance of the **service**.
+ *
+ * Often services have no configuration options and there is no need to add methods to the service
+ * provider. The provider will be no more than a constructor function with a `$get` property. For
+ * these cases the {@link auto.$provide $provide} service has additional helper methods to register
+ * services without specifying a provider.
+ *
+ * * {@link auto.$provide#provider provider(provider)} - registers a **service provider** with the
+ * {@link auto.$injector $injector}
+ * * {@link auto.$provide#constant constant(obj)} - registers a value/object that can be accessed by
+ * providers and services.
+ * * {@link auto.$provide#value value(obj)} - registers a value/object that can only be accessed by
+ * services, not providers.
+ * * {@link auto.$provide#factory factory(fn)} - registers a service **factory function**, `fn`,
+ * that will be wrapped in a **service provider** object, whose `$get` property will contain the
+ * given factory function.
+ * * {@link auto.$provide#service service(class)} - registers a **constructor function**, `class`
+ * that will be wrapped in a **service provider** object, whose `$get` property will instantiate
+ * a new object using the given constructor function.
+ *
+ * See the individual methods for more information and examples.
+ */
+
+/**
+ * @ngdoc method
+ * @name $provide#provider
+ * @description
+ *
+ * Register a **provider function** with the {@link auto.$injector $injector}. Provider functions
+ * are constructor functions, whose instances are responsible for "providing" a factory for a
+ * service.
+ *
+ * Service provider names start with the name of the service they provide followed by `Provider`.
+ * For example, the {@link ng.$log $log} service has a provider called
+ * {@link ng.$logProvider $logProvider}.
+ *
+ * Service provider objects can have additional methods which allow configuration of the provider
+ * and its service. Importantly, you can configure what kind of service is created by the `$get`
+ * method, or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a
+ * method {@link ng.$logProvider#debugEnabled debugEnabled}
+ * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the
+ * console or not.
+ *
+ * @param {string} name The name of the instance. NOTE: the provider will be available under `name +
+ 'Provider'` key.
+ * @param {(Object|function())} provider If the provider is:
+ *
+ * - `Object`: then it should have a `$get` method. The `$get` method will be invoked using
+ * {@link auto.$injector#invoke $injector.invoke()} when an instance needs to be created.
+ * - `Constructor`: a new instance of the provider will be created using
+ * {@link auto.$injector#instantiate $injector.instantiate()}, then treated as `object`.
+ *
+ * @returns {Object} registered provider instance
+
+ * @example
+ *
+ * The following example shows how to create a simple event tracking service and register it using
+ * {@link auto.$provide#provider $provide.provider()}.
+ *
+ * ```js
+ * // Define the eventTracker provider
+ * function EventTrackerProvider() {
+ * var trackingUrl = '/track';
+ *
+ * // A provider method for configuring where the tracked events should been saved
+ * this.setTrackingUrl = function(url) {
+ * trackingUrl = url;
+ * };
+ *
+ * // The service factory function
+ * this.$get = ['$http', function($http) {
+ * var trackedEvents = {};
+ * return {
+ * // Call this to track an event
+ * event: function(event) {
+ * var count = trackedEvents[event] || 0;
+ * count += 1;
+ * trackedEvents[event] = count;
+ * return count;
+ * },
+ * // Call this to save the tracked events to the trackingUrl
+ * save: function() {
+ * $http.post(trackingUrl, trackedEvents);
+ * }
+ * };
+ * }];
+ * }
+ *
+ * describe('eventTracker', function() {
+ * var postSpy;
+ *
+ * beforeEach(module(function($provide) {
+ * // Register the eventTracker provider
+ * $provide.provider('eventTracker', EventTrackerProvider);
+ * }));
+ *
+ * beforeEach(module(function(eventTrackerProvider) {
+ * // Configure eventTracker provider
+ * eventTrackerProvider.setTrackingUrl('/custom-track');
+ * }));
+ *
+ * it('tracks events', inject(function(eventTracker) {
+ * expect(eventTracker.event('login')).toEqual(1);
+ * expect(eventTracker.event('login')).toEqual(2);
+ * }));
+ *
+ * it('saves to the tracking url', inject(function(eventTracker, $http) {
+ * postSpy = spyOn($http, 'post');
+ * eventTracker.event('login');
+ * eventTracker.save();
+ * expect(postSpy).toHaveBeenCalled();
+ * expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');
+ * expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');
+ * expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
+ * }));
+ * });
+ * ```
+ */
+
+/**
+ * @ngdoc method
+ * @name $provide#factory
+ * @description
+ *
+ * Register a **service factory**, which will be called to return the service instance.
+ * This is short for registering a service where its provider consists of only a `$get` property,
+ * which is the given service factory function.
+ * You should use {@link auto.$provide#factory $provide.factory(getFn)} if you do not need to
+ * configure your service in a provider.
+ *
+ * @param {string} name The name of the instance.
+ * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand
+ * for `$provide.provider(name, {$get: $getFn})`.
+ * @returns {Object} registered provider instance
+ *
+ * @example
+ * Here is an example of registering a service
+ * ```js
+ * $provide.factory('ping', ['$http', function($http) {
+ * return function ping() {
+ * return $http.send('/ping');
+ * };
+ * }]);
+ * ```
+ * You would then inject and use this service like this:
+ * ```js
+ * someModule.controller('Ctrl', ['ping', function(ping) {
+ * ping();
+ * }]);
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#service
+ * @description
+ *
+ * Register a **service constructor**, which will be invoked with `new` to create the service
+ * instance.
+ * This is short for registering a service where its provider's `$get` property is the service
+ * constructor function that will be used to instantiate the service instance.
+ *
+ * You should use {@link auto.$provide#service $provide.service(class)} if you define your service
+ * as a type/class.
+ *
+ * @param {string} name The name of the instance.
+ * @param {Function} constructor A class (constructor function) that will be instantiated.
+ * @returns {Object} registered provider instance
+ *
+ * @example
+ * Here is an example of registering a service using
+ * {@link auto.$provide#service $provide.service(class)}.
+ * ```js
+ * var Ping = function($http) {
+ * this.$http = $http;
+ * };
+ *
+ * Ping.$inject = ['$http'];
+ *
+ * Ping.prototype.send = function() {
+ * return this.$http.get('/ping');
+ * };
+ * $provide.service('ping', Ping);
+ * ```
+ * You would then inject and use this service like this:
+ * ```js
+ * someModule.controller('Ctrl', ['ping', function(ping) {
+ * ping.send();
+ * }]);
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#value
+ * @description
+ *
+ * Register a **value service** with the {@link auto.$injector $injector}, such as a string, a
+ * number, an array, an object or a function. This is short for registering a service where its
+ * provider's `$get` property is a factory function that takes no arguments and returns the **value
+ * service**.
+ *
+ * Value services are similar to constant services, except that they cannot be injected into a
+ * module configuration function (see {@link angular.Module#config}) but they can be overridden by
+ * an Angular
+ * {@link auto.$provide#decorator decorator}.
+ *
+ * @param {string} name The name of the instance.
+ * @param {*} value The value.
+ * @returns {Object} registered provider instance
+ *
+ * @example
+ * Here are some examples of creating value services.
+ * ```js
+ * $provide.value('ADMIN_USER', 'admin');
+ *
+ * $provide.value('RoleLookup', { admin: 0, writer: 1, reader: 2 });
+ *
+ * $provide.value('halfOf', function(value) {
+ * return value / 2;
+ * });
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#constant
+ * @description
+ *
+ * Register a **constant service**, such as a string, a number, an array, an object or a function,
+ * with the {@link auto.$injector $injector}. Unlike {@link auto.$provide#value value} it can be
+ * injected into a module configuration function (see {@link angular.Module#config}) and it cannot
+ * be overridden by an Angular {@link auto.$provide#decorator decorator}.
+ *
+ * @param {string} name The name of the constant.
+ * @param {*} value The constant value.
+ * @returns {Object} registered instance
+ *
+ * @example
+ * Here a some examples of creating constants:
+ * ```js
+ * $provide.constant('SHARD_HEIGHT', 306);
+ *
+ * $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
+ *
+ * $provide.constant('double', function(value) {
+ * return value * 2;
+ * });
+ * ```
+ */
+
+
+/**
+ * @ngdoc method
+ * @name $provide#decorator
+ * @description
+ *
+ * Register a **service decorator** with the {@link auto.$injector $injector}. A service decorator
+ * intercepts the creation of a service, allowing it to override or modify the behaviour of the
+ * service. The object returned by the decorator may be the original service, or a new service
+ * object which replaces or wraps and delegates to the original service.
+ *
+ * @param {string} name The name of the service to decorate.
+ * @param {function()} decorator This function will be invoked when the service needs to be
+ * instantiated and should return the decorated service instance. The function is called using
+ * the {@link auto.$injector#invoke injector.invoke} method and is therefore fully injectable.
+ * Local injection arguments:
+ *
+ * * `$delegate` - The original service instance, which can be monkey patched, configured,
+ * decorated or delegated to.
+ *
+ * @example
+ * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
+ * calls to {@link ng.$log#error $log.warn()}.
+ * ```js
+ * $provide.decorator('$log', ['$delegate', function($delegate) {
+ * $delegate.warn = $delegate.error;
+ * return $delegate;
+ * }]);
+ * ```
+ */
+
+
+function createInjector(modulesToLoad, strictDi) {
+ strictDi = (strictDi === true);
+ var INSTANTIATING = {},
+ providerSuffix = 'Provider',
+ path = [],
+ loadedModules = new HashMap([], true),
+ providerCache = {
+ $provide: {
+ provider: supportObject(provider),
+ factory: supportObject(factory),
+ service: supportObject(service),
+ value: supportObject(value),
+ constant: supportObject(constant),
+ decorator: decorator
+ }
+ },
+ providerInjector = (providerCache.$injector =
+ createInternalInjector(providerCache, function(serviceName, caller) {
+ if (angular.isString(caller)) {
+ path.push(caller);
+ }
+ throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
+ })),
+ instanceCache = {},
+ instanceInjector = (instanceCache.$injector =
+ createInternalInjector(instanceCache, function(serviceName, caller) {
+ var provider = providerInjector.get(serviceName + providerSuffix, caller);
+ return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);
+ }));
+
+
+ forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); });
+
+ return instanceInjector;
+
+ ////////////////////////////////////
+ // $provider
+ ////////////////////////////////////
+
+ function supportObject(delegate) {
+ return function(key, value) {
+ if (isObject(key)) {
+ forEach(key, reverseParams(delegate));
+ } else {
+ return delegate(key, value);
+ }
+ };
+ }
+
+ function provider(name, provider_) {
+ assertNotHasOwnProperty(name, 'service');
+ if (isFunction(provider_) || isArray(provider_)) {
+ provider_ = providerInjector.instantiate(provider_);
+ }
+ if (!provider_.$get) {
+ throw $injectorMinErr('pget', "Provider '{0}' must define $get factory method.", name);
+ }
+ return providerCache[name + providerSuffix] = provider_;
+ }
+
+ function enforceReturnValue(name, factory) {
+ return function enforcedReturnValue() {
+ var result = instanceInjector.invoke(factory, this);
+ if (isUndefined(result)) {
+ throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name);
+ }
+ return result;
+ };
+ }
+
+ function factory(name, factoryFn, enforce) {
+ return provider(name, {
+ $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
+ });
+ }
+
+ function service(name, constructor) {
+ return factory(name, ['$injector', function($injector) {
+ return $injector.instantiate(constructor);
+ }]);
+ }
+
+ function value(name, val) { return factory(name, valueFn(val), false); }
+
+ function constant(name, value) {
+ assertNotHasOwnProperty(name, 'constant');
+ providerCache[name] = value;
+ instanceCache[name] = value;
+ }
+
+ function decorator(serviceName, decorFn) {
+ var origProvider = providerInjector.get(serviceName + providerSuffix),
+ orig$get = origProvider.$get;
+
+ origProvider.$get = function() {
+ var origInstance = instanceInjector.invoke(orig$get, origProvider);
+ return instanceInjector.invoke(decorFn, null, {$delegate: origInstance});
+ };
+ }
+
+ ////////////////////////////////////
+ // Module Loading
+ ////////////////////////////////////
+ function loadModules(modulesToLoad) {
+ var runBlocks = [], moduleFn;
+ forEach(modulesToLoad, function(module) {
+ if (loadedModules.get(module)) return;
+ loadedModules.put(module, true);
+
+ function runInvokeQueue(queue) {
+ var i, ii;
+ for (i = 0, ii = queue.length; i < ii; i++) {
+ var invokeArgs = queue[i],
+ provider = providerInjector.get(invokeArgs[0]);
+
+ provider[invokeArgs[1]].apply(provider, invokeArgs[2]);
+ }
+ }
+
+ try {
+ if (isString(module)) {
+ moduleFn = angularModule(module);
+ runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
+ runInvokeQueue(moduleFn._invokeQueue);
+ runInvokeQueue(moduleFn._configBlocks);
+ } else if (isFunction(module)) {
+ runBlocks.push(providerInjector.invoke(module));
+ } else if (isArray(module)) {
+ runBlocks.push(providerInjector.invoke(module));
+ } else {
+ assertArgFn(module, 'module');
+ }
+ } catch (e) {
+ if (isArray(module)) {
+ module = module[module.length - 1];
+ }
+ if (e.message && e.stack && e.stack.indexOf(e.message) == -1) {
+ // Safari & FF's stack traces don't contain error.message content
+ // unlike those of Chrome and IE
+ // So if stack doesn't contain message, we create a new string that contains both.
+ // Since error.stack is read-only in Safari, I'm overriding e and not e.stack here.
+ /* jshint -W022 */
+ e = e.message + '\n' + e.stack;
+ }
+ throw $injectorMinErr('modulerr', "Failed to instantiate module {0} due to:\n{1}",
+ module, e.stack || e.message || e);
+ }
+ });
+ return runBlocks;
+ }
+
+ ////////////////////////////////////
+ // internal Injector
+ ////////////////////////////////////
+
+ function createInternalInjector(cache, factory) {
+
+ function getService(serviceName, caller) {
+ if (cache.hasOwnProperty(serviceName)) {
+ if (cache[serviceName] === INSTANTIATING) {
+ throw $injectorMinErr('cdep', 'Circular dependency found: {0}',
+ serviceName + ' <- ' + path.join(' <- '));
+ }
+ return cache[serviceName];
+ } else {
+ try {
+ path.unshift(serviceName);
+ cache[serviceName] = INSTANTIATING;
+ return cache[serviceName] = factory(serviceName, caller);
+ } catch (err) {
+ if (cache[serviceName] === INSTANTIATING) {
+ delete cache[serviceName];
+ }
+ throw err;
+ } finally {
+ path.shift();
+ }
+ }
+ }
+
+ function invoke(fn, self, locals, serviceName) {
+ if (typeof locals === 'string') {
+ serviceName = locals;
+ locals = null;
+ }
+
+ var args = [],
+ $inject = annotate(fn, strictDi, serviceName),
+ length, i,
+ key;
+
+ for (i = 0, length = $inject.length; i < length; i++) {
+ key = $inject[i];
+ if (typeof key !== 'string') {
+ throw $injectorMinErr('itkn',
+ 'Incorrect injection token! Expected service name as string, got {0}', key);
+ }
+ args.push(
+ locals && locals.hasOwnProperty(key)
+ ? locals[key]
+ : getService(key, serviceName)
+ );
+ }
+ if (isArray(fn)) {
+ fn = fn[length];
+ }
+
+ // http://jsperf.com/angularjs-invoke-apply-vs-switch
+ // #5388
+ return fn.apply(self, args);
+ }
+
+ function instantiate(Type, locals, serviceName) {
+ // Check if Type is annotated and use just the given function at n-1 as parameter
+ // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
+ // Object creation: http://jsperf.com/create-constructor/2
+ var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype);
+ var returnedValue = invoke(Type, instance, locals, serviceName);
+
+ return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance;
+ }
+
+ return {
+ invoke: invoke,
+ instantiate: instantiate,
+ get: getService,
+ annotate: annotate,
+ has: function(name) {
+ return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name);
+ }
+ };
+ }
+}
+
+createInjector.$$annotate = annotate;
+
+/**
+ * @ngdoc provider
+ * @name $anchorScrollProvider
+ *
+ * @description
+ * Use `$anchorScrollProvider` to disable automatic scrolling whenever
+ * {@link ng.$location#hash $location.hash()} changes.
+ */
+function $AnchorScrollProvider() {
+
+ var autoScrollingEnabled = true;
+
+ /**
+ * @ngdoc method
+ * @name $anchorScrollProvider#disableAutoScrolling
+ *
+ * @description
+ * By default, {@link ng.$anchorScroll $anchorScroll()} will automatically detect changes to
+ * {@link ng.$location#hash $location.hash()} and scroll to the element matching the new hash.
+ * Use this method to disable automatic scrolling.
+ *
+ * If automatic scrolling is disabled, one must explicitly call
+ * {@link ng.$anchorScroll $anchorScroll()} in order to scroll to the element related to the
+ * current hash.
+ */
+ this.disableAutoScrolling = function() {
+ autoScrollingEnabled = false;
+ };
+
+ /**
+ * @ngdoc service
+ * @name $anchorScroll
+ * @kind function
+ * @requires $window
+ * @requires $location
+ * @requires $rootScope
+ *
+ * @description
+ * When called, it checks the current value of {@link ng.$location#hash $location.hash()} and
+ * scrolls to the related element, according to the rules specified in the
+ * [Html5 spec](http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document).
+ *
+ * It also watches the {@link ng.$location#hash $location.hash()} and automatically scrolls to
+ * match any anchor whenever it changes. This can be disabled by calling
+ * {@link ng.$anchorScrollProvider#disableAutoScrolling $anchorScrollProvider.disableAutoScrolling()}.
+ *
+ * Additionally, you can use its {@link ng.$anchorScroll#yOffset yOffset} property to specify a
+ * vertical scroll-offset (either fixed or dynamic).
+ *
+ * @property {(number|function|jqLite)} yOffset
+ * If set, specifies a vertical scroll-offset. This is often useful when there are fixed
+ * positioned elements at the top of the page, such as navbars, headers etc.
+ *
+ * `yOffset` can be specified in various ways:
+ * - **number**: A fixed number of pixels to be used as offset.
+ * - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return
+ * a number representing the offset (in pixels).
+ * - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The distance from
+ * the top of the page to the element's bottom will be used as offset.
+ * **Note**: The element will be taken into account only as long as its `position` is set to
+ * `fixed`. This option is useful, when dealing with responsive navbars/headers that adjust
+ * their height and/or positioning according to the viewport's size.
+ *
+ *
+ *
+ * In order for `yOffset` to work properly, scrolling should take place on the document's root and
+ * not some child element.
+ *
+
+
+ angular.module('anchorScrollOffsetExample', [])
+ .run(['$anchorScroll', function($anchorScroll) {
+ $anchorScroll.yOffset = 50; // always scroll by 50 extra pixels
+ }])
+ .controller('headerCtrl', ['$anchorScroll', '$location', '$scope',
+ function ($anchorScroll, $location, $scope) {
+ $scope.gotoAnchor = function(x) {
+ var newHash = 'anchor' + x;
+ if ($location.hash() !== newHash) {
+ // set the $location.hash to `newHash` and
+ // $anchorScroll will automatically scroll to it
+ $location.hash('anchor' + x);
+ } else {
+ // call $anchorScroll() explicitly,
+ // since $location.hash hasn't changed
+ $anchorScroll();
+ }
+ };
+ }
+ ]);
+
+
+ body {
+ padding-top: 50px;
+ }
+
+ .anchor {
+ border: 2px dashed DarkOrchid;
+ padding: 10px 10px 200px 10px;
+ }
+
+ .fixed-header {
+ background-color: rgba(0, 0, 0, 0.2);
+ height: 50px;
+ position: fixed;
+ top: 0; left: 0; right: 0;
+ }
+
+ .fixed-header > a {
+ display: inline-block;
+ margin: 5px 15px;
+ }
+
+
+ */
+ this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
+ var document = $window.document;
+
+ // Helper function to get first anchor from a NodeList
+ // (using `Array#some()` instead of `angular#forEach()` since it's more performant
+ // and working in all supported browsers.)
+ function getFirstAnchor(list) {
+ var result = null;
+ Array.prototype.some.call(list, function(element) {
+ if (nodeName_(element) === 'a') {
+ result = element;
+ return true;
+ }
+ });
+ return result;
+ }
+
+ function getYOffset() {
+
+ var offset = scroll.yOffset;
+
+ if (isFunction(offset)) {
+ offset = offset();
+ } else if (isElement(offset)) {
+ var elem = offset[0];
+ var style = $window.getComputedStyle(elem);
+ if (style.position !== 'fixed') {
+ offset = 0;
+ } else {
+ offset = elem.getBoundingClientRect().bottom;
+ }
+ } else if (!isNumber(offset)) {
+ offset = 0;
+ }
+
+ return offset;
+ }
+
+ function scrollTo(elem) {
+ if (elem) {
+ elem.scrollIntoView();
+
+ var offset = getYOffset();
+
+ if (offset) {
+ // `offset` is the number of pixels we should scroll UP in order to align `elem` properly.
+ // This is true ONLY if the call to `elem.scrollIntoView()` initially aligns `elem` at the
+ // top of the viewport.
+ //
+ // IF the number of pixels from the top of `elem` to the end of the page's content is less
+ // than the height of the viewport, then `elem.scrollIntoView()` will align the `elem` some
+ // way down the page.
+ //
+ // This is often the case for elements near the bottom of the page.
+ //
+ // In such cases we do not need to scroll the whole `offset` up, just the difference between
+ // the top of the element and the offset, which is enough to align the top of `elem` at the
+ // desired position.
+ var elemTop = elem.getBoundingClientRect().top;
+ $window.scrollBy(0, elemTop - offset);
+ }
+ } else {
+ $window.scrollTo(0, 0);
+ }
+ }
+
+ function scroll() {
+ var hash = $location.hash(), elm;
+
+ // empty hash, scroll to the top of the page
+ if (!hash) scrollTo(null);
+
+ // element with given id
+ else if ((elm = document.getElementById(hash))) scrollTo(elm);
+
+ // first anchor with given name :-D
+ else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) scrollTo(elm);
+
+ // no element and hash == 'top', scroll to the top of the page
+ else if (hash === 'top') scrollTo(null);
+ }
+
+ // does not scroll when user clicks on anchor link that is currently on
+ // (no url change, no $location.hash() change), browser native does scroll
+ if (autoScrollingEnabled) {
+ $rootScope.$watch(function autoScrollWatch() {return $location.hash();},
+ function autoScrollWatchAction(newVal, oldVal) {
+ // skip the initial scroll if $location.hash is empty
+ if (newVal === oldVal && newVal === '') return;
+
+ jqLiteDocumentLoaded(function() {
+ $rootScope.$evalAsync(scroll);
+ });
+ });
+ }
+
+ return scroll;
+ }];
+}
+
+var $animateMinErr = minErr('$animate');
+
+/**
+ * @ngdoc provider
+ * @name $animateProvider
+ *
+ * @description
+ * Default implementation of $animate that doesn't perform any animations, instead just
+ * synchronously performs DOM
+ * updates and calls done() callbacks.
+ *
+ * In order to enable animations the ngAnimate module has to be loaded.
+ *
+ * To see the functional implementation check out src/ngAnimate/animate.js
+ */
+var $AnimateProvider = ['$provide', function($provide) {
+
+
+ this.$$selectors = {};
+
+
+ /**
+ * @ngdoc method
+ * @name $animateProvider#register
+ *
+ * @description
+ * Registers a new injectable animation factory function. The factory function produces the
+ * animation object which contains callback functions for each event that is expected to be
+ * animated.
+ *
+ * * `eventFn`: `function(Element, doneFunction)` The element to animate, the `doneFunction`
+ * must be called once the element animation is complete. If a function is returned then the
+ * animation service will use this function to cancel the animation whenever a cancel event is
+ * triggered.
+ *
+ *
+ * ```js
+ * return {
+ * eventFn : function(element, done) {
+ * //code to run the animation
+ * //once complete, then run done()
+ * return function cancellationFunction() {
+ * //code to cancel the animation
+ * }
+ * }
+ * }
+ * ```
+ *
+ * @param {string} name The name of the animation.
+ * @param {Function} factory The factory function that will be executed to return the animation
+ * object.
+ */
+ this.register = function(name, factory) {
+ var key = name + '-animation';
+ if (name && name.charAt(0) != '.') throw $animateMinErr('notcsel',
+ "Expecting class selector starting with '.' got '{0}'.", name);
+ this.$$selectors[name.substr(1)] = key;
+ $provide.factory(key, factory);
+ };
+
+ /**
+ * @ngdoc method
+ * @name $animateProvider#classNameFilter
+ *
+ * @description
+ * Sets and/or returns the CSS class regular expression that is checked when performing
+ * an animation. Upon bootstrap the classNameFilter value is not set at all and will
+ * therefore enable $animate to attempt to perform an animation on any element.
+ * When setting the classNameFilter value, animations will only be performed on elements
+ * that successfully match the filter expression. This in turn can boost performance
+ * for low-powered devices as well as applications containing a lot of structural operations.
+ * @param {RegExp=} expression The className expression which will be checked against all animations
+ * @return {RegExp} The current CSS className expression value. If null then there is no expression value
+ */
+ this.classNameFilter = function(expression) {
+ if (arguments.length === 1) {
+ this.$$classNameFilter = (expression instanceof RegExp) ? expression : null;
+ }
+ return this.$$classNameFilter;
+ };
+
+ this.$get = ['$$q', '$$asyncCallback', '$rootScope', function($$q, $$asyncCallback, $rootScope) {
+
+ var currentDefer;
+
+ function runAnimationPostDigest(fn) {
+ var cancelFn, defer = $$q.defer();
+ defer.promise.$$cancelFn = function ngAnimateMaybeCancel() {
+ cancelFn && cancelFn();
+ };
+
+ $rootScope.$$postDigest(function ngAnimatePostDigest() {
+ cancelFn = fn(function ngAnimateNotifyComplete() {
+ defer.resolve();
+ });
+ });
+
+ return defer.promise;
+ }
+
+ function resolveElementClasses(element, classes) {
+ var toAdd = [], toRemove = [];
+
+ var hasClasses = createMap();
+ forEach((element.attr('class') || '').split(/\s+/), function(className) {
+ hasClasses[className] = true;
+ });
+
+ forEach(classes, function(status, className) {
+ var hasClass = hasClasses[className];
+
+ // If the most recent class manipulation (via $animate) was to remove the class, and the
+ // element currently has the class, the class is scheduled for removal. Otherwise, if
+ // the most recent class manipulation (via $animate) was to add the class, and the
+ // element does not currently have the class, the class is scheduled to be added.
+ if (status === false && hasClass) {
+ toRemove.push(className);
+ } else if (status === true && !hasClass) {
+ toAdd.push(className);
+ }
+ });
+
+ return (toAdd.length + toRemove.length) > 0 &&
+ [toAdd.length ? toAdd : null, toRemove.length ? toRemove : null];
+ }
+
+ function cachedClassManipulation(cache, classes, op) {
+ for (var i=0, ii = classes.length; i < ii; ++i) {
+ var className = classes[i];
+ cache[className] = op;
+ }
+ }
+
+ function asyncPromise() {
+ // only serve one instance of a promise in order to save CPU cycles
+ if (!currentDefer) {
+ currentDefer = $$q.defer();
+ $$asyncCallback(function() {
+ currentDefer.resolve();
+ currentDefer = null;
+ });
+ }
+ return currentDefer.promise;
+ }
+
+ function applyStyles(element, options) {
+ if (angular.isObject(options)) {
+ var styles = extend(options.from || {}, options.to || {});
+ element.css(styles);
+ }
+ }
+
+ /**
+ *
+ * @ngdoc service
+ * @name $animate
+ * @description The $animate service provides rudimentary DOM manipulation functions to
+ * insert, remove and move elements within the DOM, as well as adding and removing classes.
+ * This service is the core service used by the ngAnimate $animator service which provides
+ * high-level animation hooks for CSS and JavaScript.
+ *
+ * $animate is available in the AngularJS core, however, the ngAnimate module must be included
+ * to enable full out animation support. Otherwise, $animate will only perform simple DOM
+ * manipulation operations.
+ *
+ * To learn more about enabling animation support, click here to visit the {@link ngAnimate
+ * ngAnimate module page} as well as the {@link ngAnimate.$animate ngAnimate $animate service
+ * page}.
+ */
+ return {
+ animate: function(element, from, to) {
+ applyStyles(element, { from: from, to: to });
+ return asyncPromise();
+ },
+
+ /**
+ *
+ * @ngdoc method
+ * @name $animate#enter
+ * @kind function
+ * @description Inserts the element into the DOM either after the `after` element or
+ * as the first child within the `parent` element. When the function is called a promise
+ * is returned that will be resolved at a later time.
+ * @param {DOMElement} element the element which will be inserted into the DOM
+ * @param {DOMElement} parent the parent element which will append the element as
+ * a child (if the after element is not present)
+ * @param {DOMElement} after the sibling element which will append the element
+ * after itself
+ * @param {object=} options an optional collection of styles that will be applied to the element.
+ * @return {Promise} the animation callback promise
+ */
+ enter: function(element, parent, after, options) {
+ applyStyles(element, options);
+ after ? after.after(element)
+ : parent.prepend(element);
+ return asyncPromise();
+ },
+
+ /**
+ *
+ * @ngdoc method
+ * @name $animate#leave
+ * @kind function
+ * @description Removes the element from the DOM. When the function is called a promise
+ * is returned that will be resolved at a later time.
+ * @param {DOMElement} element the element which will be removed from the DOM
+ * @param {object=} options an optional collection of options that will be applied to the element.
+ * @return {Promise} the animation callback promise
+ */
+ leave: function(element, options) {
+ element.remove();
+ return asyncPromise();
+ },
+
+ /**
+ *
+ * @ngdoc method
+ * @name $animate#move
+ * @kind function
+ * @description Moves the position of the provided element within the DOM to be placed
+ * either after the `after` element or inside of the `parent` element. When the function
+ * is called a promise is returned that will be resolved at a later time.
+ *
+ * @param {DOMElement} element the element which will be moved around within the
+ * DOM
+ * @param {DOMElement} parent the parent element where the element will be
+ * inserted into (if the after element is not present)
+ * @param {DOMElement} after the sibling element where the element will be
+ * positioned next to
+ * @param {object=} options an optional collection of options that will be applied to the element.
+ * @return {Promise} the animation callback promise
+ */
+ move: function(element, parent, after, options) {
+ // Do not remove element before insert. Removing will cause data associated with the
+ // element to be dropped. Insert will implicitly do the remove.
+ return this.enter(element, parent, after, options);
+ },
+
+ /**
+ *
+ * @ngdoc method
+ * @name $animate#addClass
+ * @kind function
+ * @description Adds the provided className CSS class value to the provided element.
+ * When the function is called a promise is returned that will be resolved at a later time.
+ * @param {DOMElement} element the element which will have the className value
+ * added to it
+ * @param {string} className the CSS class which will be added to the element
+ * @param {object=} options an optional collection of options that will be applied to the element.
+ * @return {Promise} the animation callback promise
+ */
+ addClass: function(element, className, options) {
+ return this.setClass(element, className, [], options);
+ },
+
+ $$addClassImmediately: function(element, className, options) {
+ element = jqLite(element);
+ className = !isString(className)
+ ? (isArray(className) ? className.join(' ') : '')
+ : className;
+ forEach(element, function(element) {
+ jqLiteAddClass(element, className);
+ });
+ applyStyles(element, options);
+ return asyncPromise();
+ },
+
+ /**
+ *
+ * @ngdoc method
+ * @name $animate#removeClass
+ * @kind function
+ * @description Removes the provided className CSS class value from the provided element.
+ * When the function is called a promise is returned that will be resolved at a later time.
+ * @param {DOMElement} element the element which will have the className value
+ * removed from it
+ * @param {string} className the CSS class which will be removed from the element
+ * @param {object=} options an optional collection of options that will be applied to the element.
+ * @return {Promise} the animation callback promise
+ */
+ removeClass: function(element, className, options) {
+ return this.setClass(element, [], className, options);
+ },
+
+ $$removeClassImmediately: function(element, className, options) {
+ element = jqLite(element);
+ className = !isString(className)
+ ? (isArray(className) ? className.join(' ') : '')
+ : className;
+ forEach(element, function(element) {
+ jqLiteRemoveClass(element, className);
+ });
+ applyStyles(element, options);
+ return asyncPromise();
+ },
+
+ /**
+ *
+ * @ngdoc method
+ * @name $animate#setClass
+ * @kind function
+ * @description Adds and/or removes the given CSS classes to and from the element.
+ * When the function is called a promise is returned that will be resolved at a later time.
+ * @param {DOMElement} element the element which will have its CSS classes changed
+ * removed from it
+ * @param {string} add the CSS classes which will be added to the element
+ * @param {string} remove the CSS class which will be removed from the element
+ * @param {object=} options an optional collection of options that will be applied to the element.
+ * @return {Promise} the animation callback promise
+ */
+ setClass: function(element, add, remove, options) {
+ var self = this;
+ var STORAGE_KEY = '$$animateClasses';
+ var createdCache = false;
+ element = jqLite(element);
+
+ var cache = element.data(STORAGE_KEY);
+ if (!cache) {
+ cache = {
+ classes: {},
+ options: options
+ };
+ createdCache = true;
+ } else if (options && cache.options) {
+ cache.options = angular.extend(cache.options || {}, options);
+ }
+
+ var classes = cache.classes;
+
+ add = isArray(add) ? add : add.split(' ');
+ remove = isArray(remove) ? remove : remove.split(' ');
+ cachedClassManipulation(classes, add, true);
+ cachedClassManipulation(classes, remove, false);
+
+ if (createdCache) {
+ cache.promise = runAnimationPostDigest(function(done) {
+ var cache = element.data(STORAGE_KEY);
+ element.removeData(STORAGE_KEY);
+
+ // in the event that the element is removed before postDigest
+ // is run then the cache will be undefined and there will be
+ // no need anymore to add or remove and of the element classes
+ if (cache) {
+ var classes = resolveElementClasses(element, cache.classes);
+ if (classes) {
+ self.$$setClassImmediately(element, classes[0], classes[1], cache.options);
+ }
+ }
+
+ done();
+ });
+ element.data(STORAGE_KEY, cache);
+ }
+
+ return cache.promise;
+ },
+
+ $$setClassImmediately: function(element, add, remove, options) {
+ add && this.$$addClassImmediately(element, add);
+ remove && this.$$removeClassImmediately(element, remove);
+ applyStyles(element, options);
+ return asyncPromise();
+ },
+
+ enabled: noop,
+ cancel: noop
+ };
+ }];
+}];
+
+function $$AsyncCallbackProvider() {
+ this.$get = ['$$rAF', '$timeout', function($$rAF, $timeout) {
+ return $$rAF.supported
+ ? function(fn) { return $$rAF(fn); }
+ : function(fn) {
+ return $timeout(fn, 0, false);
+ };
+ }];
+}
+
+/* global stripHash: true */
+
+/**
+ * ! This is a private undocumented service !
+ *
+ * @name $browser
+ * @requires $log
+ * @description
+ * This object has two goals:
+ *
+ * - hide all the global state in the browser caused by the window object
+ * - abstract away all the browser specific features and inconsistencies
+ *
+ * For tests we provide {@link ngMock.$browser mock implementation} of the `$browser`
+ * service, which can be used for convenient testing of the application without the interaction with
+ * the real browser apis.
+ */
+/**
+ * @param {object} window The global window object.
+ * @param {object} document jQuery wrapped document.
+ * @param {object} $log window.console or an object with the same interface.
+ * @param {object} $sniffer $sniffer service
+ */
+function Browser(window, document, $log, $sniffer) {
+ var self = this,
+ rawDocument = document[0],
+ location = window.location,
+ history = window.history,
+ setTimeout = window.setTimeout,
+ clearTimeout = window.clearTimeout,
+ pendingDeferIds = {};
+
+ self.isMock = false;
+
+ var outstandingRequestCount = 0;
+ var outstandingRequestCallbacks = [];
+
+ // TODO(vojta): remove this temporary api
+ self.$$completeOutstandingRequest = completeOutstandingRequest;
+ self.$$incOutstandingRequestCount = function() { outstandingRequestCount++; };
+
+ /**
+ * Executes the `fn` function(supports currying) and decrements the `outstandingRequestCallbacks`
+ * counter. If the counter reaches 0, all the `outstandingRequestCallbacks` are executed.
+ */
+ function completeOutstandingRequest(fn) {
+ try {
+ fn.apply(null, sliceArgs(arguments, 1));
+ } finally {
+ outstandingRequestCount--;
+ if (outstandingRequestCount === 0) {
+ while (outstandingRequestCallbacks.length) {
+ try {
+ outstandingRequestCallbacks.pop()();
+ } catch (e) {
+ $log.error(e);
+ }
+ }
+ }
+ }
+ }
+
+ function getHash(url) {
+ var index = url.indexOf('#');
+ return index === -1 ? '' : url.substr(index + 1);
+ }
+
+ /**
+ * @private
+ * Note: this method is used only by scenario runner
+ * TODO(vojta): prefix this method with $$ ?
+ * @param {function()} callback Function that will be called when no outstanding request
+ */
+ self.notifyWhenNoOutstandingRequests = function(callback) {
+ // force browser to execute all pollFns - this is needed so that cookies and other pollers fire
+ // at some deterministic time in respect to the test runner's actions. Leaving things up to the
+ // regular poller would result in flaky tests.
+ forEach(pollFns, function(pollFn) { pollFn(); });
+
+ if (outstandingRequestCount === 0) {
+ callback();
+ } else {
+ outstandingRequestCallbacks.push(callback);
+ }
+ };
+
+ //////////////////////////////////////////////////////////////
+ // Poll Watcher API
+ //////////////////////////////////////////////////////////////
+ var pollFns = [],
+ pollTimeout;
+
+ /**
+ * @name $browser#addPollFn
+ *
+ * @param {function()} fn Poll function to add
+ *
+ * @description
+ * Adds a function to the list of functions that poller periodically executes,
+ * and starts polling if not started yet.
+ *
+ * @returns {function()} the added function
+ */
+ self.addPollFn = function(fn) {
+ if (isUndefined(pollTimeout)) startPoller(100, setTimeout);
+ pollFns.push(fn);
+ return fn;
+ };
+
+ /**
+ * @param {number} interval How often should browser call poll functions (ms)
+ * @param {function()} setTimeout Reference to a real or fake `setTimeout` function.
+ *
+ * @description
+ * Configures the poller to run in the specified intervals, using the specified
+ * setTimeout fn and kicks it off.
+ */
+ function startPoller(interval, setTimeout) {
+ (function check() {
+ forEach(pollFns, function(pollFn) { pollFn(); });
+ pollTimeout = setTimeout(check, interval);
+ })();
+ }
+
+ //////////////////////////////////////////////////////////////
+ // URL API
+ //////////////////////////////////////////////////////////////
+
+ var cachedState, lastHistoryState,
+ lastBrowserUrl = location.href,
+ baseElement = document.find('base'),
+ reloadLocation = null;
+
+ cacheState();
+ lastHistoryState = cachedState;
+
+ /**
+ * @name $browser#url
+ *
+ * @description
+ * GETTER:
+ * Without any argument, this method just returns current value of location.href.
+ *
+ * SETTER:
+ * With at least one argument, this method sets url to new value.
+ * If html5 history api supported, pushState/replaceState is used, otherwise
+ * location.href/location.replace is used.
+ * Returns its own instance to allow chaining
+ *
+ * NOTE: this api is intended for use only by the $location service. Please use the
+ * {@link ng.$location $location service} to change url.
+ *
+ * @param {string} url New url (when used as setter)
+ * @param {boolean=} replace Should new url replace current history record?
+ * @param {object=} state object to use with pushState/replaceState
+ */
+ self.url = function(url, replace, state) {
+ // In modern browsers `history.state` is `null` by default; treating it separately
+ // from `undefined` would cause `$browser.url('/foo')` to change `history.state`
+ // to undefined via `pushState`. Instead, let's change `undefined` to `null` here.
+ if (isUndefined(state)) {
+ state = null;
+ }
+
+ // Android Browser BFCache causes location, history reference to become stale.
+ if (location !== window.location) location = window.location;
+ if (history !== window.history) history = window.history;
+
+ // setter
+ if (url) {
+ var sameState = lastHistoryState === state;
+
+ // Don't change anything if previous and current URLs and states match. This also prevents
+ // IE<10 from getting into redirect loop when in LocationHashbangInHtml5Url mode.
+ // See https://github.com/angular/angular.js/commit/ffb2701
+ if (lastBrowserUrl === url && (!$sniffer.history || sameState)) {
+ return self;
+ }
+ var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url);
+ lastBrowserUrl = url;
+ lastHistoryState = state;
+ // Don't use history API if only the hash changed
+ // due to a bug in IE10/IE11 which leads
+ // to not firing a `hashchange` nor `popstate` event
+ // in some cases (see #9143).
+ if ($sniffer.history && (!sameBase || !sameState)) {
+ history[replace ? 'replaceState' : 'pushState'](state, '', url);
+ cacheState();
+ // Do the assignment again so that those two variables are referentially identical.
+ lastHistoryState = cachedState;
+ } else {
+ if (!sameBase) {
+ reloadLocation = url;
+ }
+ if (replace) {
+ location.replace(url);
+ } else if (!sameBase) {
+ location.href = url;
+ } else {
+ location.hash = getHash(url);
+ }
+ }
+ return self;
+ // getter
+ } else {
+ // - reloadLocation is needed as browsers don't allow to read out
+ // the new location.href if a reload happened.
+ // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
+ return reloadLocation || location.href.replace(/%27/g,"'");
+ }
+ };
+
+ /**
+ * @name $browser#state
+ *
+ * @description
+ * This method is a getter.
+ *
+ * Return history.state or null if history.state is undefined.
+ *
+ * @returns {object} state
+ */
+ self.state = function() {
+ return cachedState;
+ };
+
+ var urlChangeListeners = [],
+ urlChangeInit = false;
+
+ function cacheStateAndFireUrlChange() {
+ cacheState();
+ fireUrlChange();
+ }
+
+ // This variable should be used *only* inside the cacheState function.
+ var lastCachedState = null;
+ function cacheState() {
+ // This should be the only place in $browser where `history.state` is read.
+ cachedState = window.history.state;
+ cachedState = isUndefined(cachedState) ? null : cachedState;
+
+ // Prevent callbacks fo fire twice if both hashchange & popstate were fired.
+ if (equals(cachedState, lastCachedState)) {
+ cachedState = lastCachedState;
+ }
+ lastCachedState = cachedState;
+ }
+
+ function fireUrlChange() {
+ if (lastBrowserUrl === self.url() && lastHistoryState === cachedState) {
+ return;
+ }
+
+ lastBrowserUrl = self.url();
+ lastHistoryState = cachedState;
+ forEach(urlChangeListeners, function(listener) {
+ listener(self.url(), cachedState);
+ });
+ }
+
+ /**
+ * @name $browser#onUrlChange
+ *
+ * @description
+ * Register callback function that will be called, when url changes.
+ *
+ * It's only called when the url is changed from outside of angular:
+ * - user types different url into address bar
+ * - user clicks on history (forward/back) button
+ * - user clicks on a link
+ *
+ * It's not called when url is changed by $browser.url() method
+ *
+ * The listener gets called with new url as parameter.
+ *
+ * NOTE: this api is intended for use only by the $location service. Please use the
+ * {@link ng.$location $location service} to monitor url changes in angular apps.
+ *
+ * @param {function(string)} listener Listener function to be called when url changes.
+ * @return {function(string)} Returns the registered listener fn - handy if the fn is anonymous.
+ */
+ self.onUrlChange = function(callback) {
+ // TODO(vojta): refactor to use node's syntax for events
+ if (!urlChangeInit) {
+ // We listen on both (hashchange/popstate) when available, as some browsers (e.g. Opera)
+ // don't fire popstate when user change the address bar and don't fire hashchange when url
+ // changed by push/replaceState
+
+ // html5 history api - popstate event
+ if ($sniffer.history) jqLite(window).on('popstate', cacheStateAndFireUrlChange);
+ // hashchange event
+ jqLite(window).on('hashchange', cacheStateAndFireUrlChange);
+
+ urlChangeInit = true;
+ }
+
+ urlChangeListeners.push(callback);
+ return callback;
+ };
+
+ /**
+ * Checks whether the url has changed outside of Angular.
+ * Needs to be exported to be able to check for changes that have been done in sync,
+ * as hashchange/popstate events fire in async.
+ */
+ self.$$checkUrlChange = fireUrlChange;
+
+ //////////////////////////////////////////////////////////////
+ // Misc API
+ //////////////////////////////////////////////////////////////
+
+ /**
+ * @name $browser#baseHref
+ *
+ * @description
+ * Returns current
+ * (always relative - without domain)
+ *
+ * @returns {string} The current base href
+ */
+ self.baseHref = function() {
+ var href = baseElement.attr('href');
+ return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
+ };
+
+ //////////////////////////////////////////////////////////////
+ // Cookies API
+ //////////////////////////////////////////////////////////////
+ var lastCookies = {};
+ var lastCookieString = '';
+ var cookiePath = self.baseHref();
+
+ function safeDecodeURIComponent(str) {
+ try {
+ return decodeURIComponent(str);
+ } catch (e) {
+ return str;
+ }
+ }
+
+ /**
+ * @name $browser#cookies
+ *
+ * @param {string=} name Cookie name
+ * @param {string=} value Cookie value
+ *
+ * @description
+ * The cookies method provides a 'private' low level access to browser cookies.
+ * It is not meant to be used directly, use the $cookie service instead.
+ *
+ * The return values vary depending on the arguments that the method was called with as follows:
+ *
+ * - cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify
+ * it
+ * - cookies(name, value) -> set name to value, if value is undefined delete the cookie
+ * - cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that
+ * way)
+ *
+ * @returns {Object} Hash of all cookies (if called without any parameter)
+ */
+ self.cookies = function(name, value) {
+ var cookieLength, cookieArray, cookie, i, index;
+
+ if (name) {
+ if (value === undefined) {
+ rawDocument.cookie = encodeURIComponent(name) + "=;path=" + cookiePath +
+ ";expires=Thu, 01 Jan 1970 00:00:00 GMT";
+ } else {
+ if (isString(value)) {
+ cookieLength = (rawDocument.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) +
+ ';path=' + cookiePath).length + 1;
+
+ // per http://www.ietf.org/rfc/rfc2109.txt browser must allow at minimum:
+ // - 300 cookies
+ // - 20 cookies per unique domain
+ // - 4096 bytes per cookie
+ if (cookieLength > 4096) {
+ $log.warn("Cookie '" + name +
+ "' possibly not set or overflowed because it was too large (" +
+ cookieLength + " > 4096 bytes)!");
+ }
+ }
+ }
+ } else {
+ if (rawDocument.cookie !== lastCookieString) {
+ lastCookieString = rawDocument.cookie;
+ cookieArray = lastCookieString.split("; ");
+ lastCookies = {};
+
+ for (i = 0; i < cookieArray.length; i++) {
+ cookie = cookieArray[i];
+ index = cookie.indexOf('=');
+ if (index > 0) { //ignore nameless cookies
+ name = safeDecodeURIComponent(cookie.substring(0, index));
+ // the first value that is seen for a cookie is the most
+ // specific one. values for the same cookie name that
+ // follow are for less specific paths.
+ if (lastCookies[name] === undefined) {
+ lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1));
+ }
+ }
+ }
+ }
+ return lastCookies;
+ }
+ };
+
+
+ /**
+ * @name $browser#defer
+ * @param {function()} fn A function, who's execution should be deferred.
+ * @param {number=} [delay=0] of milliseconds to defer the function execution.
+ * @returns {*} DeferId that can be used to cancel the task via `$browser.defer.cancel()`.
+ *
+ * @description
+ * Executes a fn asynchronously via `setTimeout(fn, delay)`.
+ *
+ * Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using
+ * `setTimeout` in tests, the fns are queued in an array, which can be programmatically flushed
+ * via `$browser.defer.flush()`.
+ *
+ */
+ self.defer = function(fn, delay) {
+ var timeoutId;
+ outstandingRequestCount++;
+ timeoutId = setTimeout(function() {
+ delete pendingDeferIds[timeoutId];
+ completeOutstandingRequest(fn);
+ }, delay || 0);
+ pendingDeferIds[timeoutId] = true;
+ return timeoutId;
+ };
+
+
+ /**
+ * @name $browser#defer.cancel
+ *
+ * @description
+ * Cancels a deferred task identified with `deferId`.
+ *
+ * @param {*} deferId Token returned by the `$browser.defer` function.
+ * @returns {boolean} Returns `true` if the task hasn't executed yet and was successfully
+ * canceled.
+ */
+ self.defer.cancel = function(deferId) {
+ if (pendingDeferIds[deferId]) {
+ delete pendingDeferIds[deferId];
+ clearTimeout(deferId);
+ completeOutstandingRequest(noop);
+ return true;
+ }
+ return false;
+ };
+
+}
+
+function $BrowserProvider() {
+ this.$get = ['$window', '$log', '$sniffer', '$document',
+ function($window, $log, $sniffer, $document) {
+ return new Browser($window, $document, $log, $sniffer);
+ }];
+}
+
+/**
+ * @ngdoc service
+ * @name $cacheFactory
+ *
+ * @description
+ * Factory that constructs {@link $cacheFactory.Cache Cache} objects and gives access to
+ * them.
+ *
+ * ```js
+ *
+ * var cache = $cacheFactory('cacheId');
+ * expect($cacheFactory.get('cacheId')).toBe(cache);
+ * expect($cacheFactory.get('noSuchCacheId')).not.toBeDefined();
+ *
+ * cache.put("key", "value");
+ * cache.put("another key", "another value");
+ *
+ * // We've specified no options on creation
+ * expect(cache.info()).toEqual({id: 'cacheId', size: 2});
+ *
+ * ```
+ *
+ *
+ * @param {string} cacheId Name or id of the newly created cache.
+ * @param {object=} options Options object that specifies the cache behavior. Properties:
+ *
+ * - `{number=}` `capacity` — turns the cache into LRU cache.
+ *
+ * @returns {object} Newly created cache object with the following set of methods:
+ *
+ * - `{object}` `info()` — Returns id, size, and options of cache.
+ * - `{{*}}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache and returns
+ * it.
+ * - `{{*}}` `get({string} key)` — Returns cached value for `key` or undefined for cache miss.
+ * - `{void}` `remove({string} key)` — Removes a key-value pair from the cache.
+ * - `{void}` `removeAll()` — Removes all cached values.
+ * - `{void}` `destroy()` — Removes references to this cache from $cacheFactory.
+ *
+ * @example
+
+
+
+
+
+
+
+
Cached Values
+
+
+ :
+
+
+
+
Cache Info
+
+
+ :
+
+
+
+
+
+ angular.module('cacheExampleApp', []).
+ controller('CacheController', ['$scope', '$cacheFactory', function($scope, $cacheFactory) {
+ $scope.keys = [];
+ $scope.cache = $cacheFactory('cacheId');
+ $scope.put = function(key, value) {
+ if ($scope.cache.get(key) === undefined) {
+ $scope.keys.push(key);
+ }
+ $scope.cache.put(key, value === undefined ? null : value);
+ };
+ }]);
+
+
+ p {
+ margin: 10px 0 3px;
+ }
+
+
+ */
+function $CacheFactoryProvider() {
+
+ this.$get = function() {
+ var caches = {};
+
+ function cacheFactory(cacheId, options) {
+ if (cacheId in caches) {
+ throw minErr('$cacheFactory')('iid', "CacheId '{0}' is already taken!", cacheId);
+ }
+
+ var size = 0,
+ stats = extend({}, options, {id: cacheId}),
+ data = {},
+ capacity = (options && options.capacity) || Number.MAX_VALUE,
+ lruHash = {},
+ freshEnd = null,
+ staleEnd = null;
+
+ /**
+ * @ngdoc type
+ * @name $cacheFactory.Cache
+ *
+ * @description
+ * A cache object used to store and retrieve data, primarily used by
+ * {@link $http $http} and the {@link ng.directive:script script} directive to cache
+ * templates and other data.
+ *
+ * ```js
+ * angular.module('superCache')
+ * .factory('superCache', ['$cacheFactory', function($cacheFactory) {
+ * return $cacheFactory('super-cache');
+ * }]);
+ * ```
+ *
+ * Example test:
+ *
+ * ```js
+ * it('should behave like a cache', inject(function(superCache) {
+ * superCache.put('key', 'value');
+ * superCache.put('another key', 'another value');
+ *
+ * expect(superCache.info()).toEqual({
+ * id: 'super-cache',
+ * size: 2
+ * });
+ *
+ * superCache.remove('another key');
+ * expect(superCache.get('another key')).toBeUndefined();
+ *
+ * superCache.removeAll();
+ * expect(superCache.info()).toEqual({
+ * id: 'super-cache',
+ * size: 0
+ * });
+ * }));
+ * ```
+ */
+ return caches[cacheId] = {
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory.Cache#put
+ * @kind function
+ *
+ * @description
+ * Inserts a named entry into the {@link $cacheFactory.Cache Cache} object to be
+ * retrieved later, and incrementing the size of the cache if the key was not already
+ * present in the cache. If behaving like an LRU cache, it will also remove stale
+ * entries from the set.
+ *
+ * It will not insert undefined values into the cache.
+ *
+ * @param {string} key the key under which the cached data is stored.
+ * @param {*} value the value to store alongside the key. If it is undefined, the key
+ * will not be stored.
+ * @returns {*} the value stored.
+ */
+ put: function(key, value) {
+ if (capacity < Number.MAX_VALUE) {
+ var lruEntry = lruHash[key] || (lruHash[key] = {key: key});
+
+ refresh(lruEntry);
+ }
+
+ if (isUndefined(value)) return;
+ if (!(key in data)) size++;
+ data[key] = value;
+
+ if (size > capacity) {
+ this.remove(staleEnd.key);
+ }
+
+ return value;
+ },
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory.Cache#get
+ * @kind function
+ *
+ * @description
+ * Retrieves named data stored in the {@link $cacheFactory.Cache Cache} object.
+ *
+ * @param {string} key the key of the data to be retrieved
+ * @returns {*} the value stored.
+ */
+ get: function(key) {
+ if (capacity < Number.MAX_VALUE) {
+ var lruEntry = lruHash[key];
+
+ if (!lruEntry) return;
+
+ refresh(lruEntry);
+ }
+
+ return data[key];
+ },
+
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory.Cache#remove
+ * @kind function
+ *
+ * @description
+ * Removes an entry from the {@link $cacheFactory.Cache Cache} object.
+ *
+ * @param {string} key the key of the entry to be removed
+ */
+ remove: function(key) {
+ if (capacity < Number.MAX_VALUE) {
+ var lruEntry = lruHash[key];
+
+ if (!lruEntry) return;
+
+ if (lruEntry == freshEnd) freshEnd = lruEntry.p;
+ if (lruEntry == staleEnd) staleEnd = lruEntry.n;
+ link(lruEntry.n,lruEntry.p);
+
+ delete lruHash[key];
+ }
+
+ delete data[key];
+ size--;
+ },
+
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory.Cache#removeAll
+ * @kind function
+ *
+ * @description
+ * Clears the cache object of any entries.
+ */
+ removeAll: function() {
+ data = {};
+ size = 0;
+ lruHash = {};
+ freshEnd = staleEnd = null;
+ },
+
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory.Cache#destroy
+ * @kind function
+ *
+ * @description
+ * Destroys the {@link $cacheFactory.Cache Cache} object entirely,
+ * removing it from the {@link $cacheFactory $cacheFactory} set.
+ */
+ destroy: function() {
+ data = null;
+ stats = null;
+ lruHash = null;
+ delete caches[cacheId];
+ },
+
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory.Cache#info
+ * @kind function
+ *
+ * @description
+ * Retrieve information regarding a particular {@link $cacheFactory.Cache Cache}.
+ *
+ * @returns {object} an object with the following properties:
+ *
+ *
**id**: the id of the cache instance
+ *
**size**: the number of entries kept in the cache instance
+ *
**...**: any additional properties from the options object when creating the
+ * cache.
+ *
+ */
+ info: function() {
+ return extend({}, stats, {size: size});
+ }
+ };
+
+
+ /**
+ * makes the `entry` the freshEnd of the LRU linked list
+ */
+ function refresh(entry) {
+ if (entry != freshEnd) {
+ if (!staleEnd) {
+ staleEnd = entry;
+ } else if (staleEnd == entry) {
+ staleEnd = entry.n;
+ }
+
+ link(entry.n, entry.p);
+ link(entry, freshEnd);
+ freshEnd = entry;
+ freshEnd.n = null;
+ }
+ }
+
+
+ /**
+ * bidirectionally links two entries of the LRU linked list
+ */
+ function link(nextEntry, prevEntry) {
+ if (nextEntry != prevEntry) {
+ if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify
+ if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify
+ }
+ }
+ }
+
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory#info
+ *
+ * @description
+ * Get information about all the caches that have been created
+ *
+ * @returns {Object} - key-value map of `cacheId` to the result of calling `cache#info`
+ */
+ cacheFactory.info = function() {
+ var info = {};
+ forEach(caches, function(cache, cacheId) {
+ info[cacheId] = cache.info();
+ });
+ return info;
+ };
+
+
+ /**
+ * @ngdoc method
+ * @name $cacheFactory#get
+ *
+ * @description
+ * Get access to a cache object by the `cacheId` used when it was created.
+ *
+ * @param {string} cacheId Name or id of a cache to access.
+ * @returns {object} Cache object identified by the cacheId or undefined if no such cache.
+ */
+ cacheFactory.get = function(cacheId) {
+ return caches[cacheId];
+ };
+
+
+ return cacheFactory;
+ };
+}
+
+/**
+ * @ngdoc service
+ * @name $templateCache
+ *
+ * @description
+ * The first time a template is used, it is loaded in the template cache for quick retrieval. You
+ * can load templates directly into the cache in a `script` tag, or by consuming the
+ * `$templateCache` service directly.
+ *
+ * Adding via the `script` tag:
+ *
+ * ```html
+ *
+ * ```
+ *
+ * **Note:** the `script` tag containing the template does not need to be included in the `head` of
+ * the document, but it must be a descendent of the {@link ng.$rootElement $rootElement} (IE,
+ * element with ng-app attribute), otherwise the template will be ignored.
+ *
+ * Adding via the $templateCache service:
+ *
+ * ```js
+ * var myApp = angular.module('myApp', []);
+ * myApp.run(function($templateCache) {
+ * $templateCache.put('templateId.html', 'This is the content of the template');
+ * });
+ * ```
+ *
+ * To retrieve the template later, simply use it in your HTML:
+ * ```html
+ *
+ * ```
+ *
+ * or get it via Javascript:
+ * ```js
+ * $templateCache.get('templateId.html')
+ * ```
+ *
+ * See {@link ng.$cacheFactory $cacheFactory}.
+ *
+ */
+function $TemplateCacheProvider() {
+ this.$get = ['$cacheFactory', function($cacheFactory) {
+ return $cacheFactory('templates');
+ }];
+}
+
+/* ! VARIABLE/FUNCTION NAMING CONVENTIONS THAT APPLY TO THIS FILE!
+ *
+ * DOM-related variables:
+ *
+ * - "node" - DOM Node
+ * - "element" - DOM Element or Node
+ * - "$node" or "$element" - jqLite-wrapped node or element
+ *
+ *
+ * Compiler related stuff:
+ *
+ * - "linkFn" - linking fn of a single directive
+ * - "nodeLinkFn" - function that aggregates all linking fns for a particular node
+ * - "childLinkFn" - function that aggregates all linking fns for child nodes of a particular node
+ * - "compositeLinkFn" - function that aggregates all linking fns for a compilation root (nodeList)
+ */
+
+
+/**
+ * @ngdoc service
+ * @name $compile
+ * @kind function
+ *
+ * @description
+ * Compiles an HTML string or DOM into a template and produces a template function, which
+ * can then be used to link {@link ng.$rootScope.Scope `scope`} and the template together.
+ *
+ * The compilation is a process of walking the DOM tree and matching DOM elements to
+ * {@link ng.$compileProvider#directive directives}.
+ *
+ *
+ * **Note:** This document is an in-depth reference of all directive options.
+ * For a gentle introduction to directives with examples of common use cases,
+ * see the {@link guide/directive directive guide}.
+ *
+ *
+ * ## Comprehensive Directive API
+ *
+ * There are many different options for a directive.
+ *
+ * The difference resides in the return value of the factory function.
+ * You can either return a "Directive Definition Object" (see below) that defines the directive properties,
+ * or just the `postLink` function (all other properties will have the default values).
+ *
+ *
+ * **Best Practice:** It's recommended to use the "directive definition object" form.
+ *
+ * **Note:** Any unspecified options will use the default value. You can see the default values below.
+ *
+ *
+ * Therefore the above can be simplified as:
+ *
+ * ```js
+ * var myModule = angular.module(...);
+ *
+ * myModule.directive('directiveName', function factory(injectables) {
+ * var directiveDefinitionObject = {
+ * link: function postLink(scope, iElement, iAttrs) { ... }
+ * };
+ * return directiveDefinitionObject;
+ * // or
+ * // return function postLink(scope, iElement, iAttrs) { ... }
+ * });
+ * ```
+ *
+ *
+ *
+ * ### Directive Definition Object
+ *
+ * The directive definition object provides instructions to the {@link ng.$compile
+ * compiler}. The attributes are:
+ *
+ * #### `multiElement`
+ * When this property is set to true, the HTML compiler will collect DOM nodes between
+ * nodes with the attributes `directive-name-start` and `directive-name-end`, and group them
+ * together as the directive elements. It is recommended that this feature be used on directives
+ * which are not strictly behavioural (such as {@link ngClick}), and which
+ * do not manipulate or replace child nodes (such as {@link ngInclude}).
+ *
+ * #### `priority`
+ * When there are multiple directives defined on a single DOM element, sometimes it
+ * is necessary to specify the order in which the directives are applied. The `priority` is used
+ * to sort the directives before their `compile` functions get called. Priority is defined as a
+ * number. Directives with greater numerical `priority` are compiled first. Pre-link functions
+ * are also run in priority order, but post-link functions are run in reverse order. The order
+ * of directives with the same priority is undefined. The default priority is `0`.
+ *
+ * #### `terminal`
+ * If set to true then the current `priority` will be the last set of directives
+ * which will execute (any directives at the current priority will still execute
+ * as the order of execution on same `priority` is undefined). Note that expressions
+ * and other directives used in the directive's template will also be excluded from execution.
+ *
+ * #### `scope`
+ * **If set to `true`,** then a new scope will be created for this directive. If multiple directives on the
+ * same element request a new scope, only one new scope is created. The new scope rule does not
+ * apply for the root of the template since the root of the template always gets a new scope.
+ *
+ * **If set to `{}` (object hash),** then a new "isolate" scope is created. The 'isolate' scope differs from
+ * normal scope in that it does not prototypically inherit from the parent scope. This is useful
+ * when creating reusable components, which should not accidentally read or modify data in the
+ * parent scope.
+ *
+ * The 'isolate' scope takes an object hash which defines a set of local scope properties
+ * derived from the parent scope. These local properties are useful for aliasing values for
+ * templates. Locals definition is a hash of local scope property to its source:
+ *
+ * * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
+ * always a string since DOM attributes are strings. If no `attr` name is specified then the
+ * attribute name is assumed to be the same as the local name.
+ * Given `` and widget definition
+ * of `scope: { localName:'@myAttr' }`, then widget scope property `localName` will reflect
+ * the interpolated value of `hello {{name}}`. As the `name` attribute changes so will the
+ * `localName` property on the widget scope. The `name` is read from the parent scope (not
+ * component scope).
+ *
+ * * `=` or `=attr` - set up bi-directional binding between a local scope property and the
+ * parent scope property of name defined via the value of the `attr` attribute. If no `attr`
+ * name is specified then the attribute name is assumed to be the same as the local name.
+ * Given `` and widget definition of
+ * `scope: { localModel:'=myAttr' }`, then widget scope property `localModel` will reflect the
+ * value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
+ * in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent
+ * scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You
+ * can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional. If
+ * you want to shallow watch for changes (i.e. $watchCollection instead of $watch) you can use
+ * `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional).
+ *
+ * * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope.
+ * If no `attr` name is specified then the attribute name is assumed to be the same as the
+ * local name. Given `` and widget definition of
+ * `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to
+ * a function wrapper for the `count = count + value` expression. Often it's desirable to
+ * pass data from the isolated scope via an expression to the parent scope, this can be
+ * done by passing a map of local variable names and values into the expression wrapper fn.
+ * For example, if the expression is `increment(amount)` then we can specify the amount value
+ * by calling the `localFn` as `localFn({amount: 22})`.
+ *
+ *
+ * #### `bindToController`
+ * When an isolate scope is used for a component (see above), and `controllerAs` is used, `bindToController: true` will
+ * allow a component to have its properties bound to the controller, rather than to scope. When the controller
+ * is instantiated, the initial values of the isolate scope bindings are already available.
+ *
+ * #### `controller`
+ * Controller constructor function. The controller is instantiated before the
+ * pre-linking phase and it is shared with other directives (see
+ * `require` attribute). This allows the directives to communicate with each other and augment
+ * each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:
+ *
+ * * `$scope` - Current scope associated with the element
+ * * `$element` - Current element
+ * * `$attrs` - Current attributes object for the element
+ * * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope:
+ * `function([scope], cloneLinkingFn, futureParentElement)`.
+ * * `scope`: optional argument to override the scope.
+ * * `cloneLinkingFn`: optional argument to create clones of the original transcluded content.
+ * * `futureParentElement`:
+ * * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
+ * * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
+ * * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
+ * and when the `cloneLinkinFn` is passed,
+ * as those elements need to created and cloned in a special way when they are defined outside their
+ * usual containers (e.g. like `