diff --git a/.github/workflows/dump.yml b/.github/workflows/dump.yml index 315385aa7a..dc7dd686d0 100644 --- a/.github/workflows/dump.yml +++ b/.github/workflows/dump.yml @@ -10,7 +10,7 @@ jobs: one: strategy: matrix: - os: [[self-hosted, windows], macOS-latest] + os: [windows-latest, macOS-latest] runs-on: ${{ matrix.os }} steps: diff --git a/.github/workflows/master_build.yml b/.github/workflows/master_build.yml index 350181a3c8..9ef4728cb0 100644 --- a/.github/workflows/master_build.yml +++ b/.github/workflows/master_build.yml @@ -84,9 +84,9 @@ jobs: build: strategy: matrix: - os: [[self-hosted, windows], macOS-latest] + os: [windows-latest, macOS-latest] build_type: [full, client] - #os: [[self-hosted, windows], macOS-latest, ubuntu-latest] + #os: [windows-latest, macOS-latest, ubuntu-latest] # exclude: # - os: ubuntu-latest # build_type: client @@ -122,7 +122,7 @@ jobs: echo "::set-output name=symbols_archive::${{ steps.buildnumber.outputs.build_number }}-${{ matrix.build_type }}-mac-symbols.zip" fi # Windows build variables - if [ "${{ matrix.os[1] }}" = "windows" ]; then + if [ "${{ matrix.os }}" = "windows-latest" ]; then echo ::set-env name=PYTHON_EXEC::python echo ::set-env name=ZIP_COMMAND::7z echo ::set-env name=ZIP_ARGS::a @@ -154,13 +154,13 @@ jobs: echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" fi # Windows build variables - if [ "${{ matrix.os[1] }}" = "windows" ]; then + if [ "${{ matrix.os }}" = "windows-latest" ]; then echo ::set-env name=CMAKE_EXTRA::"-A x64" echo ::set-env name=HF_PFX_PASSPHRASE::${{secrets.pfx_key}} echo "::set-env name=HF_PFX_FILE::${{runner.workspace}}\build\codesign.pfx" fi - name: Clear Working Directory - if: matrix.os[1] == 'windows' + if: matrix.os == 'windows-latest' shell: bash working-directory: ${{runner.workspace}} run: rm -rf ./* @@ -171,12 +171,12 @@ jobs: - name: Create Build Directory run: cmake -E make_directory ${{runner.workspace}}/build - name: Decrypt Signing Key (Windows) - if: matrix.os[1] == 'windows' + if: matrix.os == 'windows-latest' working-directory: ${{runner.workspace}}/build shell: bash run: gpg --batch --yes -o codesign.pfx --passphrase "${{secrets.gpg_symmetric_key}}" --decrypt $GITHUB_WORKSPACE/tools/ci-scripts/codesign.pfx.gpg - name: Import Signing Key (Windows) - if: matrix.os[1] == 'windows' + if: matrix.os == 'windows-latest' working-directory: ${{runner.workspace}}/build shell: powershell run: | @@ -214,7 +214,7 @@ jobs: shell: bash run: cmake --build . --config $BUILD_TYPE --target package - name: Sign Installer (Windows) - if: matrix.os[1] == 'windows' + if: matrix.os == 'windows-latest' shell: powershell working-directory: C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64 run: .\signtool.exe sign /fd sha256 /f ${{runner.workspace}}\build\codesign.pfx /p ${{secrets.pfx_key}} /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${{runner.workspace}}\build\${env:INSTALLER} @@ -227,7 +227,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.aws_secret_access_key }} run: $PYTHON_EXEC $GITHUB_WORKSPACE/tools/ci-scripts/upload.py - name: Archive Symbols - if: (matrix.os[1] == 'windows') || (matrix.os == 'macOS-latest') + if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') working-directory: ${{runner.workspace}} shell: bash run: | @@ -237,19 +237,19 @@ jobs: cd $SYMBOLS_TEMP $ZIP_COMMAND $ZIP_ARGS ../${{ steps.buildenv1.outputs.symbols_archive }} . - name: Upload Symbols - if: (matrix.os[1] == 'windows') || (matrix.os == 'macOS-latest') + if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') working-directory: ${{runner.workspace}} shell: bash run: | curl --data-binary @${{ steps.buildenv1.outputs.symbols_archive }} "$CMAKE_BACKTRACE_URL/post?format=symbols&token=$CMAKE_BACKTRACE_SYMBOLS_TOKEN&upload_file=${{steps.buildenv1.outputs.symbols_archive}}&tag=$RELEASE_NUMBER" # - name: Debug List Symbols - # if: (matrix.os[1] == 'windows') || (matrix.os == 'macOS-latest') + # if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') # working-directory: ${{runner.workspace}} # shell: bash # run: | # unzip -v "${{runner.workspace}}/${{ steps.buildenv1.outputs.symbols_archive }}" # - name: Debug Upload Symbols Artifact - # if: (matrix.os[1] == 'windows') || (matrix.os == 'macOS-latest') + # if: (matrix.os == 'windows-latest') || (matrix.os == 'macOS-latest') # uses: actions/upload-artifact@v1 # with: # name: symbols diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index de97374107..d1ecb1bb02 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -28,7 +28,7 @@ jobs: build: strategy: matrix: - os: [[self-hosted, windows], macOS-latest] + os: [windows-latest, macOS-latest] build_type: [full] fail-fast: false runs-on: ${{matrix.os}} @@ -51,7 +51,7 @@ jobs: echo ::set-env name=CMAKE_EXTRA::"-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -G Xcode" fi # Windows build variables - if [ "${{ matrix.os[1] }}" = "windows" ]; then + if [ "${{ matrix.os }}" = "windows-latest" ]; then echo ::set-env name=PYTHON_EXEC::python echo ::set-env name=INSTALLER_EXT::exe echo ::set-env name=CMAKE_EXTRA::"-A x64" @@ -101,7 +101,7 @@ jobs: shell: bash run: cmake --build . --config $BUILD_TYPE --target package - name: Output Installer Logs - if: failure() && matrix.os[1] == 'windows' + if: failure() && matrix.os == 'windows-latest' shell: bash working-directory: ${{runner.workspace}}/build run: cat ./_CPack_Packages/win64/NSIS/NSISOutput.log @@ -120,7 +120,7 @@ jobs: run: sudo apt install -y mesa-common-dev libegl1 libglvnd-dev libdouble-conversion1 libpulse0 - name: Install python modules shell: bash - run: pip install boto3 PyGithub + run: pip install boto3 distro PyGithub - name: Create Build Environment run: cmake -E make_directory ${{runner.workspace}}/build - name: Configure CMake diff --git a/.gitignore b/.gitignore index 8061c2140d..82c9535c5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +VideoDecodeStats + # CMake CMakeCache.txt CMakeFiles/ diff --git a/BUILD.md b/BUILD.md index 877ac4f1da..bc032d4ec7 100644 --- a/BUILD.md +++ b/BUILD.md @@ -1,9 +1,13 @@ +# General Build Information + +*Last Updated on December 21, 2019* + ### OS Specific Build Guides -* [BUILD_WIN.md](BUILD_WIN.md) - complete instructions for Windows. -* [BUILD_OSX.md](BUILD_OSX.md) - additional instructions for OS X. -* [BUILD_LINUX.md](BUILD_LINUX.md) - additional instructions for Linux. -* [BUILD_ANDROID.md](BUILD_ANDROID.md) - additional instructions for Android +* [Build Windows](BUILD_WIN.md) - complete instructions for Windows. +* [Build Linux](BUILD_LINUX.md) - additional instructions for Linux. +* [Build OSX](BUILD_OSX.md) - additional instructions for OS X. +* [Build Android](BUILD_ANDROID.md) - additional instructions for Android ### Dependencies - [git](https://git-scm.com/downloads): >= 1.6 @@ -23,10 +27,10 @@ These dependencies need not be installed manually. They are automatically downlo - [QuaZip](https://sourceforge.net/projects/quazip/files/quazip/): 0.7.3 - [SDL2](https://www.libsdl.org/download-2.0.php): 2.0.3 - [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/): 4.3 -- [vcpkg](https://github.com/highfidelity/vcpkg): +- [vcpkg](https://github.com/hifi-archive/vcpkg): - [VHACD](https://github.com/virneo/v-hacd) - [zlib](http://www.zlib.net/): 1.28 (Win32 only) -- [nvtt](https://github.com/highfidelity/nvidia-texture-tools): 2.1.1 (customized) +- [nvtt](https://github.com/hifi-archive/nvidia-texture-tools): 2.1.1 (customized) The above dependencies will be downloaded, built, linked and included automatically by CMake where we require them. The CMakeLists files that handle grabbing each of the following external dependencies can be found in the [cmake/externals folder](cmake/externals). The resulting downloads, source files and binaries will be placed in the `build/ext` folder in each of the subfolders for each external project. @@ -34,7 +38,7 @@ These are not placed in your normal build tree when doing an out of source build #### CMake -Hifi uses CMake to generate build files and project files for your platform. +Athena uses CMake to generate build files and project files for your platform. #### Qt CMake will download Qt 5.12.3 using vcpkg. @@ -49,7 +53,7 @@ This can either be entered directly into your shell session before you build or #### Vcpkg -Hifi uses vcpkg to download and build dependencies. +Athena uses vcpkg to download and build dependencies. You do not need to install vcpkg. Building the dependencies can be lengthy and the resulting files will be stored in your OS temp directory. diff --git a/BUILD_ANDROID.md b/BUILD_ANDROID.md index 3047cb827d..0bea3e5a90 100644 --- a/BUILD_ANDROID.md +++ b/BUILD_ANDROID.md @@ -1,6 +1,10 @@ +# Build Android + +*Last Updated on December 21, 2019* + Please read the [general build guide](BUILD.md) for information on building other platforms. Only Android specific instructions are found in this file. **Note that these instructions apply to building for Oculus Quest.** -# Dependencies +## Dependencies Building is currently supported on Windows, OSX and Linux, but developers intending to do work on the library dependencies are strongly urged to use 64 bit Linux as a build platform. @@ -27,7 +31,7 @@ Still in the _SDK Tools_ tab, click _Show Package Details_. Select CMake 3.6.4. Also, make sure the NDK installed version is 18 (or higher). -# Environment +## Environment ### Create a keystore in Android Studio Follow the directions [here](https://developer.android.com/studio/publish/app-signing#generate-key) to create a keystore file. You can save it anywhere (preferably not in the `hifi` folder). @@ -62,9 +66,9 @@ The above code to suppress modules is not necessary, but will speed up the build ### Clone the repository -`git clone https://github.com/highfidelity/hifi.git ` +`git clone https://github.com/kasenvr/project-athena.git` -# Building & Running +## Building & Running ### Building Modules @@ -99,9 +103,9 @@ For the interface modules, you also need to select the activity to launch. Note the 's' in Permission**s**Checker for the Quest. -Now you are able to run your module! Click the green play button in the top toolbar of Android Studio -r -# Troubleshooting +Now you are able to run your module! Click the green play button in the top toolbar of Android Studio. + +## Troubleshooting To view a more complete debug log, diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index c0cef86ba4..f88e7173c8 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -1,4 +1,6 @@ -# Linux build guide +# Build Linux + +*Last Updated on January 20, 2020* Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file. @@ -14,88 +16,96 @@ sudo add-apt-repository universe sudo apt-get update ``` #### Install build tools: -1. First update the repositiories: +- First update the repositories: ```bash sudo apt-get update -y sudo apt-get upgrade -y ``` -1. git +- git ```bash sudo apt-get install git -y ``` Verify by git --version -1. g++ +- g++ ```bash sudo apt-get install g++ -y ``` Verify by g++ --version -1. *Ubuntu 18.04* cmake +- *Ubuntu 18.04* cmake ```bash sudo apt-get install cmake -y ``` -Verify by git --version -1. *Ubuntu 16.04* cmake +Verify by cmake --version +- *Ubuntu 16.04* cmake ```bash wget https://cmake.org/files/v3.14/cmake-3.14.2-Linux-x86_64.sh sudo sh cmake-3.14.2-Linux-x86_64.sh --prefix=/usr/local --exclude-subdir ``` #### Install build dependencies: -1. OpenSSL +- OpenSSL: ```bash sudo apt-get install libssl-dev ``` Verify with `openssl version` -1. OpenGL -Verify (first install mesa-utils - `sudo apt install mesa-utils -y`) by `glxinfo | grep "OpenGL version"` +- OpenGL: ```bash sudo apt-get install libgl1-mesa-dev -y sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so.346.35 /usr/lib/x86_64-linux-gnu/libGL.so.1.2.0 ``` +- Verify OpenGL: + - First install mesa-utils with the command `sudo apt install mesa-utils -y` + - Then run `glxinfo | grep "OpenGL version"` #### To compile interface in a server you must install: ```bash sudo apt-get -y install libpulse0 libnss3 libnspr4 libfontconfig1 libxcursor1 libxcomposite1 libxtst6 libxslt1.1 ``` -1. Misc dependencies +- Misc dependencies: ```bash sudo apt-get install libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev zlib1g-dev ``` -1. To compile interface in a server you must install: +- Install Python 3 and required packages: ```bash -sudo apt-get -y install libpulse0 libnss3 libnspr4 libfontconfig1 libxcursor1 libxcomposite1 libxtst6 libxslt1.1 +sudo apt-get install python python3 python3-distro ``` -1. Install Python 3: -```bash -sudo apt-get install python3.6 -``` -1. Install node, required to build the jsdoc documentation +- Install node, required to build the jsdoc documentation: ```bash sudo apt-get install nodejs ``` -### Get code and checkout the tag you need +### Get code and checkout the branch you need Clone this repository: ```bash -git clone https://github.com/highfidelity/hifi.git +git clone https://github.com/kasenvr/project-athena.git ``` -To compile a RELEASE version checkout the tag you need getting a list of all tags: +To compile a DEV version checkout the branch you need. To get a list of all tags: ```bash git fetch -a -git tags ``` -Then checkout last tag with: +Then checkout the main branch with: ```bash -git checkout tags/v0.79.0 +git checkout kasen/core ``` +### Using a custom Qt build + +Qt binaries are only provided for Ubuntu. In order to build on other distributions, a Qt5 install needs to be provided as follows: + +* Set `VIRCADIA_USE_PREBUILT_QT=1` +* Set `VIRCADIA_USE_QT_VERSION` to the Qt version (defaults to `5.12.3`) +* Set `HIFI_QT_BASE=/path/to/qt` + +Qt must be installed in `$HIFI_QT_BASE/$VIRCADIA_USE_QT_VERSION/qt5-install`. + ### Compiling Create the build directory: ```bash -mkdir -p hifi/build -cd hifi/build +cd project-athena +mkdir build +cd build ``` Prepare makefiles: @@ -103,7 +113,7 @@ Prepare makefiles: cmake .. ``` -* If cmake fails with a vcpkg error - delete /tmp/hifi/vcpkg. +- If cmake fails with a vcpkg error - delete /tmp/hifi/vcpkg. Start compilation of the server and get a cup of coffee: ```bash @@ -115,7 +125,15 @@ To compile interface: make interface ``` -In a server, it does not make sense to compile interface +The commands above will compile with a single thread. If you have enough memory, +you can decrease your build time using the `-j` flag. Since most x64 CPUs +support two threads per core, this works out to CPU_COUNT*2. As an example, if +you have a 2 core machine, you could use: +``` +make -j4 interface +``` + +In a server, it does not make sense to compile interface. ### Running the software @@ -142,6 +160,13 @@ Running interface: Go to localhost in the running interface. +#### Notes + +If your goal is to set up a development environment, it is desirable to set the +directory that vcpkg builds into with the `HIFI_VCPKG_BASE` environment variable. +For example, you might set `HIFI_VCPKG_BASE` to `/home/$USER/vcpkg`. +By default, vcpkg will build in the system `/tmp` directory. + ##### Ubuntu 18.04 only In Ubuntu 18.04 there is a problem related with NVidia driver library version. @@ -169,11 +194,11 @@ It can be worked around following these steps: `make` `sudo make install` -1.. Link compiled files: +1. Link compiled files: `sudo ln -s /usr/local/lib/libnvcore.so /usr/lib/libnvcore.so` `sudo ln -s /usr/local/lib/libnvimage.so /usr/lib/libnvimage.so` `sudo ln -s /usr/local/lib/libnvmath.so /usr/lib/libnvmath.so` `sudo ln -s /usr/local/lib/libnvtt.so /usr/lib/libnvtt.so` -1. After running this steps you can run interface: +1. After running these steps you can run interface: `interface/interface` diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 875d49bcb8..69cfed7de9 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -1,4 +1,8 @@ -Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only macOS specific instructions are found in this file. +# Build OSX + +*Last Updated on April 30, 2019* + +Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only macOS specific instructions are found in this document. ### Homebrew diff --git a/BUILD_WIN.md b/BUILD_WIN.md index bc6e5c8386..bdab7e6e6d 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -1,5 +1,9 @@ -This is a stand-alone guide for creating your first High Fidelity build for Windows 64-bit. -## Building High Fidelity +# Build Windows + +*Last Updated on January 13, 2020* + +This is a stand-alone guide for creating your first Vircadia build for Windows 64-bit. + Note: We are now using Visual Studio 2017 or 2019 and Qt 5.12.3. If you are upgrading from previous versions, do a clean uninstall of those versions before going through this guide. @@ -29,15 +33,21 @@ If you already have Visual Studio installed and need to add Python, open the "Ad If you do not wish to use the Python installation bundled with Visual Studio, you can download the installer from [here](https://www.python.org/downloads/). Ensure you get version 3.6.6 or higher. -### Step 2. Installing CMake +### Step 2. Python Dependencies + +In a command-line that can access Python's pip you will need to run the following command: + +`pip install distro` + +### Step 3. Installing CMake Download and install the latest version of CMake 3.15. * Note that earlier versions of CMake will work, but there is a specific bug related to the interaction of Visual Studio 2019 and CMake versions prior to 3.15 that will cause Visual Studio to rebuild far more than it needs to on every build Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.15 Version page](https://cmake.org/files/v3.15/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted. -### Step 3. Create VCPKG environment variable -In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them. +### Step 4. Create VCPKG environment variable +In the next step, you will use CMake to build Project Athena. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them. To create this variable: * Naviagte to 'Edit the System Environment Variables' Through the start menu. @@ -55,7 +65,7 @@ To create this variable: * Set "Variable name" to `HIFI_VCPKG_BOOTSTRAP` * Set "Variable value" to `1` -### Step 4. Running CMake to Generate Build Files +### Step 5. Running CMake to Generate Build Files Run Command Prompt from Start and run the following commands: `cd "%HIFI_DIR%"` @@ -70,15 +80,15 @@ Run `cmake .. -G "Visual Studio 16 2019" -A x64`. Where `%HIFI_DIR%` is the directory for the highfidelity repository. -### Step 5. Making a Build +### Step 6. Making a Build -Open `%HIFI_DIR%\build\hifi.sln` using Visual Studio. +Open `%HIFI_DIR%\build\athena.sln` using Visual Studio. Change the Solution Configuration (menu ribbon under the menu bar, next to the green play button) from "Debug" to "Release" for best performance. Run from the menu bar `Build > Build Solution`. -### Step 6. Testing Interface +### Step 7. Testing Interface Create another environment variable (see Step #3) * Set "Variable name": `_NO_DEBUG_HEAP` @@ -88,7 +98,7 @@ Restart Visual Studio again. In Visual Studio, right+click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run from the menu bar `Debug > Start Debugging`. -Now, you should have a full build of High Fidelity and be able to run the Interface using Visual Studio. Please check our [Docs](https://wiki.highfidelity.com/wiki/Main_Page) for more information regarding the programming workflow. +Now, you should have a full build of Project Athena and be able to run the Interface using Visual Studio. Please check our [Docs](https://wiki.highfidelity.com/wiki/Main_Page) for more information regarding the programming workflow. Note: You can also run Interface by launching it from command line or File Explorer from `%HIFI_DIR%\build\interface\Release\interface.exe` @@ -97,7 +107,7 @@ Note: You can also run Interface by launching it from command line or File Explo For any problems after Step #6, first try this: * Delete your locally cloned copy of the highfidelity repository * Restart your computer -* Redownload the [repository](https://github.com/highfidelity/hifi) +* Redownload the [repository](https://github.com/kasenvr/project-athena) * Restart directions from Step #6 #### CMake gives you the same error message repeatedly after the build fails diff --git a/CMakeLists.txt b/CMakeLists.txt index 059bcf98d5..4bf7b8bc56 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,40 @@ else() cmake_minimum_required(VERSION 3.2) endif() + +# Passing of variables to vcpkg +# +# vcpkg runs cmake scripts in an isolated environment, see this for details: +# https://github.com/Microsoft/vcpkg/issues/3712 +# +# Here's how this works and how we work around this issue: +# +# 1. This file (CMakeLists.txt) runs first and is authoritative. It is the one +# that reads the environment, sets variables and sets a default value. +# 2. It writes the contents of the variables to +# $CMAKE_CURRENT_BINARY_DIR/_env/$VARNAME +# 3. hifi_vcpkg.py takes the _env directory, and copies it to the vcpkg dir. +# This solves the issue of CMakeLists.txt not knowing where the vcpkg dir is. +# 4. cmake/ports/*/portfile.cmake does know where the vcpkg dir is, and can +# read the _env that was copied there to obtain the variable's name. +# +# To ensure no old data could be accidentally read, the _env directories are +# deleted on each execution and fully recreated. + +# Ensure nothing is kept from any previous run +file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/_env") +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_env") + +# Base URL for externally downloaded files +set(EXTERNAL_BUILD_ASSETS "https://athena-public.s3.amazonaws.com") + +if( DEFINED ENV{EXTERNAL_BUILD_ASSETS} ) + set(EXTERNAL_BUILD_ASSETS "$ENV{EXTERNAL_BUILD_ASSETS}") +endif() + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" "${EXTERNAL_BUILD_ASSETS}") +MESSAGE(STATUS "EXTERNAL_BUILD_ASSETS: ${EXTERNAL_BUILD_ASSETS}") + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros/TargetPython.cmake") target_python() @@ -59,7 +93,7 @@ endif() option(VCPKG_APPLOCAL_DEPS OFF) -project(hifi) +project(athena) include("cmake/init.cmake") include("cmake/compiler.cmake") option(VCPKG_APPLOCAL_DEPS OFF) diff --git a/CODING_STANDARD.md b/CODING_STANDARD.md index 17f7ecb2f2..fd1843e981 100644 --- a/CODING_STANDARD.md +++ b/CODING_STANDARD.md @@ -976,15 +976,18 @@ while (true) { #### [4.3.4] Source files (header and implementation) must include a boilerplate. -Boilerplates should include the filename, location, creator, copyright, and Apache 2.0 License information and be placed at the top of the file. +Boilerplates should include the filename, location, creator, copyright Project Athena contributors, and Apache 2.0 License +information. This should be placed at the top of the file. If editing an existing file that is copyright High Fidelity, add a +second copyright line, copyright Project Athena contributors. ```cpp // // NodeList.h // libraries/shared/src // -// Created by Stephen Birarda on 2/15/13. +// Created by Stephen Birarda on 15 Feb 2013. // Copyright 2013 High Fidelity, Inc. +// Copyright 2020 Project Athena contributors. // // This is where you could place an optional one line comment about the file. // diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f9a54f1adc..a62e4b2825 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,4 @@ -The project embraces distributed development and if you'd like to help, we'll pay you -- find out more at [Worklist.net](https://worklist.net). If you find a small bug and have a fix, pull requests are welcome. If you'd like to get paid for your work, make sure you report the bug via a job on Worklist.net. - -We're hiring! We're looking for skilled developers; send your resume to hiring@highfidelity.io +The project embraces distributed development and if you'd like to help, it would be greatly appreciated. Just open a pull request with the revisions. Contributing === @@ -8,7 +6,7 @@ Contributing 2. Clone your fork of the repository locally ``` - git clone git://github.com/USERNAME/hifi.git + git clone git://github.com/USERNAME/project-athena.git ``` 3. Create a new branch @@ -22,15 +20,16 @@ Contributing 6. Update your branch ``` - git remote add upstream https://github.com/highfidelity/hifi - git pull upstream master + git remote add upstream https://github.com/kasenvr/project-athena + git pull upstream kasen/core ``` Resolve any conflicts that arise with this step. + 7. Push to your fork ``` - git push origin master + git push origin kasen/core ``` 8. Submit a pull request @@ -39,10 +38,10 @@ Contributing Reporting Bugs === 1. Always update to the latest code on master, we make many merges every day and it is possible the bug has already been fixed! -2. Search jobs [on Worklist](https://worklist.net) to make sure that somebody has not already reported the same bug. -3. Add a [job on Worklist](https://worklist.net/job/add) including information about your system and how to reproduce the bug. +2. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already reported the same bug. +3. [Add](https://github.com/kasenvr/project-athena/issues/new) your report to the issues list! -Requesting a feature +Requesting a Feature === -1. Search the [the Worklist](https://worklist.net) to make sure that somebody has not already requested the same feature. If you find a matching request, feel free to add any additional comments to the existing issue. -2. Add a [job on Worklist](https://worklist.net/job/add) that is labeled as a Feature (and select any other appropriate Labels) and includes a detailed description of your request. +1. Search [issues](https://github.com/kasenvr/project-athena/issues) to make sure that somebody has not already requested the same feature. +2. [Add](https://github.com/kasenvr/project-athena/issues/new) your request to the issues list! diff --git a/INSTALL.md b/INSTALL.md index bcbf93eef3..10858200e7 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,10 +1,10 @@ -Follow the [build guide](BUILD.md) to figure out how to build High Fidelity for your platform. +# Creating an Installer + +Follow the [build guide](BUILD.md) to figure out how to build Project Athena for your platform. During generation, CMake should produce an `install` target and a `package` target. -### Install - -The `install` target will copy the High Fidelity targets and their dependencies to your `CMAKE_INSTALL_PREFIX`. +The `install` target will copy the Project Athena targets and their dependencies to your `CMAKE_INSTALL_PREFIX`. This variable is set by the `project(hifi)` command in `CMakeLists.txt` to `C:/Program Files/hifi` and stored in `build/CMakeCache.txt` ### Packaging @@ -60,8 +60,9 @@ To produce an executable installer on Windows, the following are required: 1. Install version 10.15.0 LTS 1. Perform a clean cmake from a new terminal. -1. Open the `hifi.sln` Solution and select the Release configuration. -1. Build the Solution. +1. Open the `athena.sln` solution and select the Release configuration. +1. Build the solution. +1. Build `packaged-server-console-npm-install` (found under **hidden/Server Console**) 1. Build `packaged-server-console` (found under **Server Console**) This will add 2 folders to `build\server-console\` - `server-console-win32-x64` and `x64` @@ -72,7 +73,7 @@ To produce an executable installer on Windows, the following are required: 1. [npm]() Install version 10.15.0 LTS -1. Perform a clean cmake. +1. Perform a clean CMake. 1. Perform a Release build of ALL_BUILD 1. Perform a Release build of `packaged-server-console` This will add a folder to `build\server-console\` - diff --git a/LICENSE b/LICENSE index deb80afc19..f88e751de5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ -Copyright (c) 2013-2018, High Fidelity, Inc. +Copyright (c) 2013-2019, High Fidelity, Inc. +Copyright (c) 2019-2020, Project Athena Contributors. All rights reserved. -licensing@highfidelity.io +https://projectathena.io Licensed under the Apache License version 2.0 (the "License"); You may not use this software except in compliance with the License. diff --git a/README.md b/README.md index 674bd5a64d..f61a60d431 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,53 @@ -High Fidelity (hifi) is an early-stage technology lab experimenting with Virtual Worlds and VR. +# Vircadia -This repository contains the source to many of the components in our -alpha-stage virtual world. The project embraces distributed development. -If you find a small bug and have a fix, pull requests are welcome. +### What is this? -We're hiring! We're looking for skilled developers; -send your resume to hiring@highfidelity.com +Vircadia is a 3D social software project seeking to incrementally bring about a truly free and open metaverse, in desktop and XR. -##### Chat with us -Come chat with us in [our Gitter](https://gitter.im/highfidelity/hifi) if you have any questions or just want to say hi! +### [Download](https://vircadia.com/download-vircadia/) -Documentation -========= -Documentation is available at [docs.highfidelity.com](https://docs.highfidelity.com), if something is missing, please suggest it via a new job on Worklist (add to the hifi-docs project). +### Releases -There is also detailed [documentation on our coding standards](CODING_STANDARD.md). +[View Releases here](https://github.com/kasenvr/project-athena/releases/) -Contributor License Agreement (CLA) -========= -Technology companies frequently receive and use code from contributors outside the company's development team. Outside code can be a tremendous resource, but it also carries responsibility. Best practice for accepting outside contributions consists of an Apache-type Contributor License Agreement (CLA). We have modeled the High Fidelity CLA after the CLA that Google presents to developers for contributions to their projects. This CLA does not transfer ownership of code, instead simply granting a non-exclusive right for High Fidelity to use the code you’ve contributed. In that regard, you should be sure you have permission if the work relates to or uses the resources of a company that you work for. You will be asked to sign our CLA when you create your first PR or when the CLA is updated. You can also [review it here](https://gist.githubusercontent.com/hifi-gustavo/fef8f06a8233d42a0040d45c3efb97a9/raw/9981827eb94f0b18666083670b6f6a02929fb402/High%2520Fidelity%2520CLA). We sincerely appreciate your contribution and efforts toward the success of the platform. +### How to build the Interface -Build Instructions -========= -All information required to build is found in the [build guide](BUILD.md). +[For Windows](https://github.com/kasenvr/project-athena/blob/kasen/core/BUILD_WIN.md) -Running Interface -=== -When you launch interface, you will automatically connect to our default domain: "root.highfidelity.io". +[For Linux](https://github.com/kasenvr/project-athena/blob/kasen/core/BUILD_LINUX.md) -If you don't see anything, make sure your preferences are pointing to -root.highfidelity.io (set your domain via Cmnd+D/Cntrl+D). If you still have no luck, -it's possible our servers are down. If you're experiencing a major bug, let us know by -adding an issue to this repository. Include details about your computer and how to -reproduce the bug in your issue. +[For Linux - Athena Builder](https://github.com/daleglass/athena-builder) -To move around in-world, use the arrow keys (and Shift + up/down to fly up or -down) or W A S D, and E or C to fly up/down. All of the other possible options -and features are available via menus in the Interface application. +### How to deploy a Server -Running your own servers -======== -The assignment-client and domain-server are architectural components that will allow -you to run the full stack of the virtual world. +[For Windows and Linux](https://vircadia.com/download-vircadia/#server) -In order to set up your own virtual world, you need to set up and run your own -local "domain". +### How to build a Server -The domain-server gives a number different types of assignments to the assignment-client -for different features: audio, avatars, voxels, particles, meta-voxels and models. +[For Linux - Athena Builder](https://github.com/daleglass/athena-builder) -Follow the instructions in the [build guide](BUILD.md) to build the various components. +### Boot to Metaverse: The Goal -From the domain-server build directory, launch a domain-server. +Having a place to experience adventure, a place to relax with calm breath, that's a world to live in. An engine to support infinite combinations and possibilities of worlds without censorship and interruption, that's a metaverse. Finding a way to make infinite realities our reality, that's the dream. - ./domain-server +### Boot to Metaverse: The Technicals -Then, run an assignment-client. The assignment-client uses localhost as its assignment-server -and talks to it on port 40102 (the default domain-server port). +Many developers have had personal combinations of High Fidelity from C++ modifications to different default scripts, all of which are lost to time as their fullest potential is never truly shared and propagated through the system. -In a new Terminal window, run: +The goal of this project is to achieve the metaverse dream through shared contribution and building. Setting goals that are achievable yet meaningful is key to making proper forward progress on the technical front whilst maintaining morale. - ./assignment-client +### Why High Fidelity's Virtual Reality Platform? -Any target can be terminated with Ctrl-C (SIGINT) in the associated Terminal window. +Because of all the options, it is the only starting point that is open-source, cross-platform, fully VR integrated + fully desktop integrated with an aim for quality visuals and performance. It also provides a foundation to build from including components like entity management, full body IK, etc. -This assignment-client will grab one assignment from the domain-server. You can tell the -assignment-client what type you want it to be with the `-t` option. You can also run an -assignment-client that forks off *n* assignment-clients with the `-n` option. The `-min` -and `-max` options allow you to set a range of required assignment-clients. This allows -you to have flexibility in the number of assignment-clients that are running. -See `--help` for more options. +WebXR offers the open-source and decentralized aspect but does not have any of the full featured starting points such as avatars, IK, etc. which means that a lot of ground work will have to be laid to make something functional. Far more work will need to be done to create a truly seamless and extensive experience as well. - ./assignment-client --min 6 --max 20 +Platforms like NeosVR or VRChat are not viable from go due to their fundamental closed-source and centralized nature. A metaverse to live in cannot have the keys handed over to any singular entity, if any at all. -To test things out, you'll need to run the Interface client. +We need to do the best we can with what we've got and our best bet as open source developers is to not redesign the wheel if we can help it! -To access your local domain in Interface, open your Preferences. On OS X, this is available -in the Interface menu. On Linux, you'll find it in the File menu. Enter "localhost" in the -"Domain server" field. +### Contribution -If everything worked, you should see that you are connected to at least one server. -Nice work! +A special thanks to the contributors of Vircadia. + +[Contribution](CONTRIBUTING.md) diff --git a/README_hifi.md b/README_hifi.md new file mode 100644 index 0000000000..46433a155c --- /dev/null +++ b/README_hifi.md @@ -0,0 +1,86 @@ +High Fidelity (hifi) is an early-stage technology lab experimenting with Virtual Worlds and VR. + +This repository contains the source to many of the components in our +alpha-stage virtual world. The project embraces distributed development. +If you'd like to help, we'll pay you -- find out more at [Worklist.net](https://worklist.net). +If you find a small bug and have a fix, pull requests are welcome. If you'd +like to get paid for your work, make sure you report the bug via a job on +[Worklist.net](https://worklist.net). + +We're hiring! We're looking for skilled developers; +send your resume to hiring@highfidelity.com + +##### Chat with us +Come chat with us in [our Gitter](https://gitter.im/highfidelity/hifi) if you have any questions or just want to say hi! + +Documentation +========= +Documentation is available at [docs.highfidelity.com](https://docs.highfidelity.com), if something is missing, please suggest it via a new job on Worklist (add to the hifi-docs project). + +There is also detailed [documentation on our coding standards](CODING_STANDARD.md). + +Contributor License Agreement (CLA) +========= +Technology companies frequently receive and use code from contributors outside the company's development team. Outside code can be a tremendous resource, but it also carries responsibility. Best practice for accepting outside contributions consists of an Apache-type Contributor License Agreement (CLA). We have modeled the High Fidelity CLA after the CLA that Google presents to developers for contributions to their projects. This CLA does not transfer ownership of code, instead simply granting a non-exclusive right for High Fidelity to use the code you’ve contributed. In that regard, you should be sure you have permission if the work relates to or uses the resources of a company that you work for. You will be asked to sign our CLA when you create your first PR or when the CLA is updated. You can also [review it here](https://gist.githubusercontent.com/hifi-gustavo/fef8f06a8233d42a0040d45c3efb97a9/raw/9981827eb94f0b18666083670b6f6a02929fb402/High%2520Fidelity%2520CLA). We sincerely appreciate your contribution and efforts toward the success of the platform. + +Build Instructions +========= +All information required to build is found in the [build guide](BUILD.md). + +Running Interface +=== +When you launch interface, you will automatically connect to our default domain: "root.highfidelity.io". + +If you don't see anything, make sure your preferences are pointing to +root.highfidelity.io (set your domain via Cmnd+D/Cntrl+D). If you still have no luck, +it's possible our servers are down. If you're experiencing a major bug, let us know by +adding an issue to this repository. Include details about your computer and how to +reproduce the bug in your issue. + +To move around in-world, use the arrow keys (and Shift + up/down to fly up or +down) or W A S D, and E or C to fly up/down. All of the other possible options +and features are available via menus in the Interface application. + +Running your own servers +======== +The assignment-client and domain-server are architectural components that will allow +you to run the full stack of the virtual world. + +In order to set up your own virtual world, you need to set up and run your own +local "domain". + +The domain-server gives a number different types of assignments to the assignment-client +for different features: audio, avatars, voxels, particles, meta-voxels and models. + +Follow the instructions in the [build guide](BUILD.md) to build the various components. + +From the domain-server build directory, launch a domain-server. + + ./domain-server + +Then, run an assignment-client. The assignment-client uses localhost as its assignment-server +and talks to it on port 40102 (the default domain-server port). + +In a new Terminal window, run: + + ./assignment-client + +Any target can be terminated with Ctrl-C (SIGINT) in the associated Terminal window. + +This assignment-client will grab one assignment from the domain-server. You can tell the +assignment-client what type you want it to be with the `-t` option. You can also run an +assignment-client that forks off *n* assignment-clients with the `-n` option. The `-min` +and `-max` options allow you to set a range of required assignment-clients. This allows +you to have flexibility in the number of assignment-clients that are running. +See `--help` for more options. + + ./assignment-client --min 6 --max 20 + +To test things out, you'll need to run the Interface client. + +To access your local domain in Interface, open your Preferences. On OS X, this is available +in the Interface menu. On Linux, you'll find it in the File menu. Enter "localhost" in the +"Domain server" field. + +If everything worked, you should see that you are connected to at least one server. +Nice work! diff --git a/assignment-client/src/avatars/MixerAvatar.cpp b/assignment-client/src/avatars/MixerAvatar.cpp index 5203d25af6..f3d7bb8995 100644 --- a/assignment-client/src/avatars/MixerAvatar.cpp +++ b/assignment-client/src/avatars/MixerAvatar.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include "ClientTraitsHandler.h" @@ -235,7 +236,7 @@ void MixerAvatar::requestCurrentOwnership() { QNetworkRequest networkRequest; networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + QUrl requestURL = MetaverseAPI::getCurrentMetaverseServerURL(); requestURL.setPath(POP_MARKETPLACE_API); networkRequest.setUrl(requestURL); diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index 6bbf4a0e3b..a6ab382781 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "../AssignmentDynamicFactory.h" diff --git a/cmake/externals/GifCreator/CMakeLists.txt b/cmake/externals/GifCreator/CMakeLists.txt index 094f5612a9..bacfefd48b 100644 --- a/cmake/externals/GifCreator/CMakeLists.txt +++ b/cmake/externals/GifCreator/CMakeLists.txt @@ -3,7 +3,7 @@ set(EXTERNAL_NAME GifCreator) include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/GifCreator.zip + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/GifCreator.zip" URL_MD5 8ac8ef5196f47c658dce784df5ecdb70 CONFIGURE_COMMAND "" BUILD_COMMAND "" @@ -17,4 +17,4 @@ set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/src/${EXTERNAL_NAME} CACHE PATH "List of GifCreator include directories") \ No newline at end of file +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/src/${EXTERNAL_NAME} CACHE PATH "List of GifCreator include directories") diff --git a/cmake/externals/LibOVR/CMakeLists.txt b/cmake/externals/LibOVR/CMakeLists.txt index 53c4c2976c..872d0e5fef 100644 --- a/cmake/externals/LibOVR/CMakeLists.txt +++ b/cmake/externals/LibOVR/CMakeLists.txt @@ -17,7 +17,7 @@ if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://hifi-public.s3.amazonaws.com/dependencies/ovr_sdk_win_1.35.0.zip + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/ovr_sdk_win_1.35.0.zip" URL_MD5 1e3e8b2101387af07ff9c841d0ea285e CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= PATCH_COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/LibOVRCMakeLists.txt" /CMakeLists.txt @@ -38,7 +38,7 @@ elseif(APPLE) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/ovr_sdk_macos_0.5.0.1.tar.gz + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/ovr_sdk_macos_0.5.0.1.tar.gz" URL_MD5 0a0785a04fb285f64f62267388344ad6 CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/cmake/externals/LibOVRPlatform/CMakeLists.txt b/cmake/externals/LibOVRPlatform/CMakeLists.txt index adf89823f2..40e6ae123c 100644 --- a/cmake/externals/LibOVRPlatform/CMakeLists.txt +++ b/cmake/externals/LibOVRPlatform/CMakeLists.txt @@ -9,7 +9,7 @@ if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/OVRPlatformSDK_v1.10.0.zip + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/OVRPlatformSDK_v1.10.0.zip" URL_MD5 e6c8264af16d904e6506acd5172fa0a9 CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/cmake/externals/crashpad/CMakeLists.txt b/cmake/externals/crashpad/CMakeLists.txt index 34348b6418..e519ead0ee 100644 --- a/cmake/externals/crashpad/CMakeLists.txt +++ b/cmake/externals/crashpad/CMakeLists.txt @@ -6,7 +6,7 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (WIN32) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/crashpad_062317.1.zip + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/crashpad_062317.1.zip" URL_MD5 9c84b77f5f23daf939da1371825ed2b1 CONFIGURE_COMMAND "" BUILD_COMMAND "" @@ -25,7 +25,7 @@ if (WIN32) elseif (APPLE) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/crashpad_mac_070318.zip + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/crashpad_mac_070318.zip" URL_MD5 ba1501dc163591ac2d1be74946967e2a CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/cmake/externals/hifiAudioCodec/CMakeLists.txt b/cmake/externals/hifiAudioCodec/CMakeLists.txt index 5d439cd519..31454ace50 100644 --- a/cmake/externals/hifiAudioCodec/CMakeLists.txt +++ b/cmake/externals/hifiAudioCodec/CMakeLists.txt @@ -6,16 +6,16 @@ set(EXTERNAL_NAME hifiAudioCodec) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) if (WIN32) - set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-win-2.0.zip) + set(DOWNLOAD_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/codecSDK-win-2.0.zip") set(DOWNLOAD_MD5 9199d4dbd6b16bed736b235efe980e67) elseif (APPLE) - set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-mac-2.0.zip) + set(DOWNLOAD_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/codecSDK-mac-2.0.zip") set(DOWNLOAD_MD5 21649881e7d5dc94f922179be96f76ba) elseif (ANDROID) - set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-android-2.0.zip) + set(DOWNLOAD_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/codecSDK-android-2.0.zip") set(DOWNLOAD_MD5 aef2a852600d498d58aa586668191683) elseif (UNIX) - set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/codecSDK-linux-2.0.zip) + set(DOWNLOAD_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/codecSDK-linux-2.0.zip") set(DOWNLOAD_MD5 67fb7755f9bcafb98a9fceea53bc7481) else() return() diff --git a/cmake/externals/neuron/CMakeLists.txt b/cmake/externals/neuron/CMakeLists.txt index 049e175354..45b18f86cd 100644 --- a/cmake/externals/neuron/CMakeLists.txt +++ b/cmake/externals/neuron/CMakeLists.txt @@ -4,7 +4,7 @@ set(EXTERNAL_NAME neuron) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(NEURON_URL "https://public.highfidelity.com/dependencies/neuron_datareader_b.12.2.zip") +set(NEURON_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/neuron_datareader_b.12.2.zip") set(NEURON_URL_MD5 "84273ad2200bf86a9279d1f412a822ca") ExternalProject_Add(${EXTERNAL_NAME} diff --git a/cmake/externals/sixense/CMakeLists.txt b/cmake/externals/sixense/CMakeLists.txt index 35f7758820..c2fb8ad8f9 100644 --- a/cmake/externals/sixense/CMakeLists.txt +++ b/cmake/externals/sixense/CMakeLists.txt @@ -4,15 +4,15 @@ set(EXTERNAL_NAME sixense) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -#set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_062612.zip") +#set(SIXENSE_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/SixenseSDK_062612.zip") #set(SIXENSE_URL_MD5 "10cc8dc470d2ac1244a88cf04bc549cc") #set(SIXENSE_NEW_LAYOUT 0) -set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_071615.zip") +set(SIXENSE_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/SixenseSDK_071615.zip") set(SIXENSE_URL_MD5 "752a3901f334124e9cffc2ba4136ef7d") set(SIXENSE_NEW_LAYOUT 1) -#set(SIXENSE_URL "https://public.highfidelity.com/dependencies/SixenseSDK_102215.zip") +#set(SIXENSE_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/SixenseSDK_102215.zip") #set(SIXENSE_URL_MD5 "93c3a6795cce777a0f472b09532935f1") #set(SIXENSE_NEW_LAYOUT 1) diff --git a/cmake/externals/steamworks/CMakeLists.txt b/cmake/externals/steamworks/CMakeLists.txt index eb61d22f8b..1ec72d7d28 100644 --- a/cmake/externals/steamworks/CMakeLists.txt +++ b/cmake/externals/steamworks/CMakeLists.txt @@ -4,7 +4,7 @@ set(EXTERNAL_NAME steamworks) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) -set(STEAMWORKS_URL "https://public.highfidelity.com/dependencies/steamworks_sdk_137.zip") +set(STEAMWORKS_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/steamworks_sdk_137.zip") set(STEAMWORKS_URL_MD5 "95ba9d0e3ddc04f8a8be17d2da806cbb") ExternalProject_Add( diff --git a/cmake/externals/tbb/CMakeLists.txt b/cmake/externals/tbb/CMakeLists.txt index 1788922ef2..8f8f2d3030 100644 --- a/cmake/externals/tbb/CMakeLists.txt +++ b/cmake/externals/tbb/CMakeLists.txt @@ -3,13 +3,13 @@ set(EXTERNAL_NAME tbb) include(ExternalProject) if (WIN32) - set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_win_slim.zip) + set(DOWNLOAD_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/tbb2017_20170604oss_win_slim.zip") set(DOWNLOAD_MD5 065934458e3db88397f3d10e7eea536c) elseif (APPLE) - set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_mac_slim.tar.gz) + set(DOWNLOAD_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/tbb2017_20170604oss_mac_slim.tar.gz") set(DOWNLOAD_MD5 62bde626b396f8e1a85c6a8ded1d8105) else () - set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/tbb2017_20170604oss_lin_slim.tar.gz) + set(DOWNLOAD_URL "${EXTERNAL_BUILD_ASSETS}/dependencies/tbb2017_20170604oss_lin_slim.tar.gz") set(DOWNLOAD_MD5 2a5c721f40fa3503ffc12c18dd00011c) endif () diff --git a/cmake/externals/wasapi/CMakeLists.txt b/cmake/externals/wasapi/CMakeLists.txt index 286d18e2b5..bc8148c278 100644 --- a/cmake/externals/wasapi/CMakeLists.txt +++ b/cmake/externals/wasapi/CMakeLists.txt @@ -6,7 +6,7 @@ if (WIN32) include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - URL https://public.highfidelity.com/dependencies/qtaudio_wasapi13.zip + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/qtaudio_wasapi13.zip" URL_MD5 aa56a45f19c18caee13d29a40d1d7d28 CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/cmake/init.cmake b/cmake/init.cmake index bc97e67a4a..ca95ad1a72 100644 --- a/cmake/init.cmake +++ b/cmake/init.cmake @@ -63,4 +63,12 @@ if (APPLE) set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep") set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "") set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") -endif() \ No newline at end of file +endif() + +if (UNIX) + # Static libs result in duplicated constructor and destructor calls on Linux + # and crashes on exit, and perhaps loss of global state on plugin loads. + # + # This will need to be looked at closely before Linux can have a static build. + set(BUILD_SHARED_LIBS ON) +endif () diff --git a/cmake/installer/installer-header.bmp b/cmake/installer/installer-header.bmp index 7588a338b1..2d262d3ef9 100644 Binary files a/cmake/installer/installer-header.bmp and b/cmake/installer/installer-header.bmp differ diff --git a/cmake/installer/installer.ico b/cmake/installer/installer.ico index d42eae96ad..63a3eff482 100644 Binary files a/cmake/installer/installer.ico and b/cmake/installer/installer.ico differ diff --git a/cmake/installer/uninstaller-header.bmp b/cmake/installer/uninstaller-header.bmp index d43166ded3..2d262d3ef9 100644 Binary files a/cmake/installer/uninstaller-header.bmp and b/cmake/installer/uninstaller-header.bmp differ diff --git a/cmake/macros/GenerateInstallers.cmake b/cmake/macros/GenerateInstallers.cmake index acafd9b6c7..83bdefeada 100644 --- a/cmake/macros/GenerateInstallers.cmake +++ b/cmake/macros/GenerateInstallers.cmake @@ -18,20 +18,20 @@ macro(GENERATE_INSTALLERS) if (CLIENT_ONLY) set(_PACKAGE_NAME_EXTRA "-Interface") set(INSTALLER_TYPE "client_only") - string(REGEX REPLACE "High Fidelity" "High Fidelity Interface" _DISPLAY_NAME ${BUILD_ORGANIZATION}) + string(REGEX REPLACE "Project Athena" "Project Athena Interface" _DISPLAY_NAME ${BUILD_ORGANIZATION}) elseif (SERVER_ONLY) set(_PACKAGE_NAME_EXTRA "-Sandbox") set(INSTALLER_TYPE "server_only") - string(REGEX REPLACE "High Fidelity" "High Fidelity Sandbox" _DISPLAY_NAME ${BUILD_ORGANIZATION}) + string(REGEX REPLACE "Project Athena" "Project Athena Sandbox" _DISPLAY_NAME ${BUILD_ORGANIZATION}) else () set(_DISPLAY_NAME ${BUILD_ORGANIZATION}) set(INSTALLER_TYPE "full") endif () set(CPACK_PACKAGE_NAME ${_DISPLAY_NAME}) - set(CPACK_PACKAGE_VENDOR "High Fidelity") + set(CPACK_PACKAGE_VENDOR "Project Athena") set(CPACK_PACKAGE_VERSION ${BUILD_VERSION}) - set(CPACK_PACKAGE_FILE_NAME "HighFidelity-Beta${_PACKAGE_NAME_EXTRA}-${BUILD_VERSION}") + set(CPACK_PACKAGE_FILE_NAME "ProjectAthena-Alpha${_PACKAGE_NAME_EXTRA}-${BUILD_VERSION}") set(CPACK_NSIS_DISPLAY_NAME ${_DISPLAY_NAME}) set(CPACK_NSIS_PACKAGE_NAME ${_DISPLAY_NAME}) if (PR_BUILD) @@ -118,11 +118,11 @@ macro(GENERATE_INSTALLERS) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") if (BUILD_CLIENT) - cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "High Fidelity Interface") + cpack_add_component(${CLIENT_COMPONENT} DISPLAY_NAME "Project Athena Interface") endif () if (BUILD_SERVER) - cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "High Fidelity Sandbox") + cpack_add_component(${SERVER_COMPONENT} DISPLAY_NAME "Project Athena Sandbox") endif () include(CPack) diff --git a/cmake/macros/SetPackagingParameters.cmake b/cmake/macros/SetPackagingParameters.cmake index cbc89d7724..935996850b 100644 --- a/cmake/macros/SetPackagingParameters.cmake +++ b/cmake/macros/SetPackagingParameters.cmake @@ -35,7 +35,7 @@ macro(SET_PACKAGING_PARAMETERS) set(DEPLOY_PACKAGE TRUE) set(PRODUCTION_BUILD 1) set(BUILD_VERSION ${RELEASE_NUMBER}) - set(BUILD_ORGANIZATION "High Fidelity") + set(BUILD_ORGANIZATION "Project Athena") set(HIGH_FIDELITY_PROTOCOL "hifi") set(HIGH_FIDELITY_APP_PROTOCOL "hifiapp") set(INTERFACE_BUNDLE_NAME "interface") @@ -60,7 +60,7 @@ macro(SET_PACKAGING_PARAMETERS) set(DEPLOY_PACKAGE TRUE) set(PR_BUILD 1) set(BUILD_VERSION "PR${RELEASE_NUMBER}") - set(BUILD_ORGANIZATION "High Fidelity - PR${RELEASE_NUMBER}") + set(BUILD_ORGANIZATION "Project Athena - PR${RELEASE_NUMBER}") set(INTERFACE_BUNDLE_NAME "interface") set(INTERFACE_ICON_PREFIX "interface-beta") @@ -69,7 +69,7 @@ macro(SET_PACKAGING_PARAMETERS) else () set(DEV_BUILD 1) set(BUILD_VERSION "dev") - set(BUILD_ORGANIZATION "High Fidelity - ${BUILD_VERSION}") + set(BUILD_ORGANIZATION "Project Athena - ${BUILD_VERSION}") set(INTERFACE_BUNDLE_NAME "interface") set(INTERFACE_ICON_PREFIX "interface-beta") @@ -171,21 +171,21 @@ macro(SET_PACKAGING_PARAMETERS) # shortcut names if (PRODUCTION_BUILD) - set(INTERFACE_SHORTCUT_NAME "High Fidelity") + set(INTERFACE_SHORTCUT_NAME "Project Athena") set(CONSOLE_SHORTCUT_NAME "Console") set(SANDBOX_SHORTCUT_NAME "Sandbox") set(APP_USER_MODEL_ID "com.highfidelity.console") else () - set(INTERFACE_SHORTCUT_NAME "High Fidelity - ${BUILD_VERSION_NO_SHA}") + set(INTERFACE_SHORTCUT_NAME "Project Athena - ${BUILD_VERSION_NO_SHA}") set(CONSOLE_SHORTCUT_NAME "Console - ${BUILD_VERSION_NO_SHA}") set(SANDBOX_SHORTCUT_NAME "Sandbox - ${BUILD_VERSION_NO_SHA}") endif () set(INTERFACE_HF_SHORTCUT_NAME "${INTERFACE_SHORTCUT_NAME}") - set(CONSOLE_HF_SHORTCUT_NAME "High Fidelity ${CONSOLE_SHORTCUT_NAME}") - set(SANDBOX_HF_SHORTCUT_NAME "High Fidelity ${SANDBOX_SHORTCUT_NAME}") + set(CONSOLE_HF_SHORTCUT_NAME "Project Athena ${CONSOLE_SHORTCUT_NAME}") + set(SANDBOX_HF_SHORTCUT_NAME "Project Athena ${SANDBOX_SHORTCUT_NAME}") - set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "High Fidelity") + set(PRE_SANDBOX_INTERFACE_SHORTCUT_NAME "Project Athena") set(PRE_SANDBOX_CONSOLE_SHORTCUT_NAME "Server Console") # check if we need to find signtool diff --git a/cmake/macros/TargetOpus.cmake b/cmake/macros/TargetOpus.cmake new file mode 100644 index 0000000000..a8faf5139e --- /dev/null +++ b/cmake/macros/TargetOpus.cmake @@ -0,0 +1,13 @@ +# +# Created by Michael Bailey on 12/20/2019 +# Copyright 2019 Michael Bailey +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# +macro(TARGET_opus) + find_library(OPUS_LIBRARY_RELEASE NAMES opus PATHS ${VCPKG_INSTALL_ROOT}/lib) + find_library(OPUS_LIBRARY_DEBUG NAMES opus PATHS ${VCPKG_INSTALL_ROOT}/debug/lib) + select_library_configurations(OPUS) + target_link_libraries(${TARGET_NAME} ${OPUS_LIBRARY}) +endmacro() diff --git a/cmake/macros/TargetPolyvox.cmake b/cmake/macros/TargetPolyvox.cmake index 1779ab21f7..576b454f57 100644 --- a/cmake/macros/TargetPolyvox.cmake +++ b/cmake/macros/TargetPolyvox.cmake @@ -21,23 +21,6 @@ macro(TARGET_POLYVOX) list(APPEND POLYVOX_LIBRARY_DEBUG ${POLYVOX_UTIL_LIBRARY_DEBUG}) select_library_configurations(POLYVOX) list(APPEND POLYVOX_INCLUDE_DIRS ${VCPKG_INSTALL_ROOT}/include) - if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - set(_LIB_GLOBS) - if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(_PV_LIBRARIES ${POLYVOX_LIBRARY_DEBUG}) - else() - set(_PV_LIBRARIES ${POLYVOX_LIBRARY_RELEASE}) - endif() - foreach(_lib ${_PV_LIBRARIES}) - list(APPEND _LIB_GLOBS ${_lib}*) - endforeach() - add_custom_command( - TARGET ${TARGET_NAME} - POST_BUILD - COMMAND cp - ARGS -d ${_LIB_GLOBS} ${CMAKE_BINARY_DIR} - ) - endif() endif() target_link_libraries(${TARGET_NAME} ${POLYVOX_LIBRARIES}) target_include_directories(${TARGET_NAME} PUBLIC ${POLYVOX_INCLUDE_DIRS}) diff --git a/cmake/ports/aristo/portfile.cmake b/cmake/ports/aristo/portfile.cmake index 5c3259a34a..532e1304f4 100644 --- a/cmake/ports/aristo/portfile.cmake +++ b/cmake/ports/aristo/portfile.cmake @@ -5,7 +5,7 @@ set(MASTER_COPY_SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src) if (WIN32) vcpkg_download_distfile( ARISTO_SOURCE_ARCHIVE - URLS https://hifi-public.s3.amazonaws.com/seth/aristo-0.8.1-windows.zip + URLS https://athena-public.s3.amazonaws.com/seth/aristo-0.8.1-windows.zip SHA512 05179c63b72a1c9f5be8a7a2b7389025da683400dbf819e5a6199dd6473c56774d2885182dc5a11cb6324058d228a4ead832222e8b3e1bebaa4c61982e85f0a8 FILENAME aristo-0.8.1-windows.zip ) diff --git a/cmake/ports/etc2comp/portfile.cmake b/cmake/ports/etc2comp/portfile.cmake index d25f24cd39..343f67169b 100644 --- a/cmake/ports/etc2comp/portfile.cmake +++ b/cmake/ports/etc2comp/portfile.cmake @@ -19,7 +19,7 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO highfidelity/etc2comp + REPO kasenvr/etc2comp REF 7f1843bf07825c21cab711360c1ddbad04641036 SHA512 d747076acda8537d39585858c793a35c3dcc9ef283d723619a47f8c81ec1454c95b3340ad35f0655a939eae5b8271c801c48a9a7568311a01903a344c44af25b HEAD_REF master diff --git a/cmake/ports/glad/portfile.cmake b/cmake/ports/glad/portfile.cmake index a52a9c7f9e..56ee59e0d4 100644 --- a/cmake/ports/glad/portfile.cmake +++ b/cmake/ports/glad/portfile.cmake @@ -4,14 +4,14 @@ vcpkg_check_linkage(ONLY_STATIC_LIBRARY) if (ANDROID) vcpkg_download_distfile( SOURCE_ARCHIVE - URLS https://public.highfidelity.com/dependencies/glad/glad32es.zip + URLS https://athena-public.s3.amazonaws.com/dependencies/glad/glad32es.zip SHA512 2e02ac633eed8f2ba2adbf96ea85d08998f48dd2e9ec9a88ec3c25f48eaf1405371d258066327c783772fcb3793bdb82bd7375fdabb2ba5e2ce0835468b17f65 ) else() # else Linux desktop vcpkg_download_distfile( SOURCE_ARCHIVE - URLS https://public.highfidelity.com/dependencies/glad/glad45.zip + URLS https://athena-public.s3.amazonaws.com/dependencies/glad/glad45.zip SHA512 653a7b873f9fbc52e0ab95006cc3143bc7b6f62c6e032bc994e87669273468f37978525c9af5efe36f924cb4acd221eb664ad9af0ce4bf711b4f1be724c0065e FILENAME glad45.zip ) diff --git a/cmake/ports/hifi-deps/CONTROL b/cmake/ports/hifi-deps/CONTROL index 155187a9a7..d4b4acd4c5 100644 --- a/cmake/ports/hifi-deps/CONTROL +++ b/cmake/ports/hifi-deps/CONTROL @@ -1,4 +1,4 @@ Source: hifi-deps Version: 0.1.4-github-actions Description: Collected dependencies for High Fidelity applications -Build-Depends: bullet3, draco, etc2comp, glad, glm, nvtt, openexr (!android), openssl (windows), polyvox, tbb (!android), vhacd, webrtc (!android), zlib +Build-Depends: bullet3, draco, etc2comp, glad, glm, nvtt, openexr (!android), openssl (windows), opus, polyvox, tbb (!android), vhacd, webrtc (!android), zlib diff --git a/cmake/ports/hifi-scribe/portfile.cmake b/cmake/ports/hifi-scribe/portfile.cmake index 2b69f7b887..498e8a455b 100644 --- a/cmake/ports/hifi-scribe/portfile.cmake +++ b/cmake/ports/hifi-scribe/portfile.cmake @@ -3,7 +3,7 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO highfidelity/scribe + REPO kasenvr/scribe REF 1bd638a36ca771e5a68d01985b6389b71835cbd2 SHA512 dbe241d86df3912e544f6b9839873f9875df54efc93822b145e7b13243eaf2e3d690bc8a28b1e52d05bdcd7e68fca6b0b2f5c43ffd0f56a9b7a50d54dcf9e31e HEAD_REF master diff --git a/cmake/ports/nvtt/portfile.cmake b/cmake/ports/nvtt/portfile.cmake index 4cbe05b692..c7bf068e13 100644 --- a/cmake/ports/nvtt/portfile.cmake +++ b/cmake/ports/nvtt/portfile.cmake @@ -9,7 +9,7 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO highfidelity/nvidia-texture-tools + REPO kasenvr/nvidia-texture-tools REF 330c4d56274a0f602a5c70596e2eb670a4ed56c2 SHA512 4c0bc2f369120d696cc27710b6d33086b27eef55f537ec66b9a5c8b1839bc2426c0413670b0f65be52c5d353468f0126dfe024be1f0690611d4d7e33ac530127 HEAD_REF master diff --git a/cmake/ports/openssl-android/portfile.cmake b/cmake/ports/openssl-android/portfile.cmake index 54936d254d..fd74637d00 100644 --- a/cmake/ports/openssl-android/portfile.cmake +++ b/cmake/ports/openssl-android/portfile.cmake @@ -2,10 +2,12 @@ include(vcpkg_common_functions) set(OPENSSL_VERSION 1.1.0g) set(MASTER_COPY_SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src) +file(READ "${VCPKG_ROOT_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" EXTERNAL_BUILD_ASSETS) + message("MASTER_COPY_SOURCE_PATH ${MASTER_COPY_SOURCE_PATH}") vcpkg_download_distfile( OPENSSL_SOURCE_ARCHIVE - URLS https://hifi-public.s3.amazonaws.com/dependencies/android/openssl-1.1.0g_armv8.tgz?versionId=AiiPjmgUZTgNj7YV1EEx2lL47aDvvvAW + URLS "${EXTERNAL_BUILD_ASSETS}/dependencies/android/openssl-1.1.0g_armv8.tgz%3FversionId=AiiPjmgUZTgNj7YV1EEx2lL47aDvvvAW" SHA512 5d7bb6e5d3db2340449e2789bcd72da821f0e57483bac46cf06f735dffb5d73c1ca7cc53dd48f3b3979d0fe22b3ae61997c516fc0c4611af4b4b7f480e42b992 FILENAME openssl-1.1.0g_armv8.tgz ) diff --git a/cmake/ports/opus/CONTROL b/cmake/ports/opus/CONTROL new file mode 100644 index 0000000000..4314774ab5 --- /dev/null +++ b/cmake/ports/opus/CONTROL @@ -0,0 +1,3 @@ +Source: opus +Version: 1.3.1 +Description: Totally open, royalty-free, highly versatile audio codec diff --git a/cmake/ports/opus/portfile.cmake b/cmake/ports/opus/portfile.cmake new file mode 100644 index 0000000000..bf23718df8 --- /dev/null +++ b/cmake/ports/opus/portfile.cmake @@ -0,0 +1,28 @@ +include(vcpkg_common_functions) + +vcpkg_from_github( + OUT_SOURCE_PATH + SOURCE_PATH + REPO + xiph/opus + REF + e85ed7726db5d677c9c0677298ea0cb9c65bdd23 + SHA512 + a8c7e5bf383c06f1fdffd44d9b5f658f31eb4800cb59d12da95ddaeb5646f7a7b03025f4663362b888b1374d4cc69154f006ba07b5840ec61ddc1a1af01d6c54 + HEAD_REF + master) + +vcpkg_configure_cmake(SOURCE_PATH ${SOURCE_PATH} PREFER_NINJA) +vcpkg_install_cmake() +vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/Opus) +vcpkg_copy_pdbs() + +file(INSTALL + ${SOURCE_PATH}/COPYING + DESTINATION + ${CURRENT_PACKAGES_DIR}/share/opus + RENAME copyright) + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/lib/cmake + ${CURRENT_PACKAGES_DIR}/lib/cmake + ${CURRENT_PACKAGES_DIR}/debug/include) diff --git a/cmake/ports/polyvox/portfile.cmake b/cmake/ports/polyvox/portfile.cmake index 81dc707517..54cc74d4dd 100644 --- a/cmake/ports/polyvox/portfile.cmake +++ b/cmake/ports/polyvox/portfile.cmake @@ -3,7 +3,7 @@ include(vcpkg_common_functions) # else Linux desktop vcpkg_download_distfile( SOURCE_ARCHIVE - URLS https://public.highfidelity.com/dependencies/polyvox-master-2015-7-15.zip + URLS https://athena-public.s3.amazonaws.com/dependencies/polyvox-master-2015-7-15.zip SHA512 cc04cd43ae74b9c7bb065953540c0048053fcba6b52dc4218b3d9431fba178d65ad4f6c53cc1122ba61d0ab4061e99a7ebbb15db80011d607c5070ebebf8eddc FILENAME polyvox.zip ) @@ -56,6 +56,7 @@ else() file(RENAME ${CURRENT_PACKAGES_DIR}/include/PolyVoxUtil ${CURRENT_PACKAGES_DIR}/include/PolyVoxUtil.temp) file(RENAME ${CURRENT_PACKAGES_DIR}/include/PolyVoxUtil.temp/PolyVoxUtil ${CURRENT_PACKAGES_DIR}/include/PolyVoxUtil) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/include/PolyVoxUtil.temp) + file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/share/doc) endif() file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/lib/Release) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/lib/RelWithDebInfo) diff --git a/cmake/ports/quazip/portfile.cmake b/cmake/ports/quazip/portfile.cmake index 66326319f7..07a8ebc3c3 100644 --- a/cmake/ports/quazip/portfile.cmake +++ b/cmake/ports/quazip/portfile.cmake @@ -1,8 +1,10 @@ include(vcpkg_common_functions) +file(READ "${VCPKG_ROOT_DIR}/_env/QT_CMAKE_PREFIX_PATH.txt" QT_CMAKE_PREFIX_PATH) + vcpkg_download_distfile( SOURCE_ARCHIVE - URLS https://public.highfidelity.com/dependencies/quazip-0.7.3.zip + URLS https://athena-public.s3.amazonaws.com/dependencies/quazip-0.7.3.zip SHA512 b2d812b6346317fd6d8f4f1344ad48b721d697c429acc8b7e7cb776ce5cba15a59efd64b2c5ae1f31b5a3c928014f084aa1379fd55d8a452a6cf4fd510b3afcc FILENAME quazip.zip ) @@ -16,7 +18,7 @@ vcpkg_extract_source_archive_ex( vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} PREFER_NINJA - OPTIONS -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_PREFIX_PATH=$ENV{QT_CMAKE_PREFIX_PATH} -DBUILD_WITH_QT4=OFF + OPTIONS -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_PREFIX_PATH=${QT_CMAKE_PREFIX_PATH} -DBUILD_WITH_QT4=OFF ) vcpkg_install_cmake() diff --git a/cmake/ports/sdl2/CONTROL b/cmake/ports/sdl2/CONTROL index 9f195d5e75..ec60fc09ba 100644 --- a/cmake/ports/sdl2/CONTROL +++ b/cmake/ports/sdl2/CONTROL @@ -1,6 +1,5 @@ Source: sdl2 -Version: 2.0.10-1 -Homepage: https://github.com/SDL-Mirror/SDL +Version: 2.0.10-2 Description: Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D. Feature: vulkan diff --git a/cmake/ports/sdl2/fix-space-in-path.patch b/cmake/ports/sdl2/fix-space-in-path.patch new file mode 100644 index 0000000000..ed7a1e7125 --- /dev/null +++ b/cmake/ports/sdl2/fix-space-in-path.patch @@ -0,0 +1,24 @@ +diff -ur a/CMakeLists.txt b/CMakeLists.txt +--- a/CMakeLists.txt 2019-07-23 21:41:00.000000000 +0200 ++++ b/CMakeLists.txt 2019-10-27 20:26:38.000000000 +0100 +@@ -257,7 +257,7 @@ + # General includes + include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include) + if(USE_GCC OR USE_CLANG) +- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -idirafter ${SDL2_SOURCE_DIR}/src/video/khronos") ++ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -idirafter \"${SDL2_SOURCE_DIR}/src/video/khronos\"") + else() + include_directories(${SDL2_SOURCE_DIR}/src/video/khronos) + endif() +diff -ur a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake +--- a/cmake/sdlchecks.cmake 2019-07-23 21:41:00.000000000 +0200 ++++ b/cmake/sdlchecks.cmake 2019-10-27 20:27:10.000000000 +0100 +@@ -1086,7 +1086,7 @@ + set(HAVE_SDL_JOYSTICK TRUE) + file(GLOB HIDAPI_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/hidapi/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${HIDAPI_SOURCES}) +- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUSB_CFLAGS} -I${SDL2_SOURCE_DIR}/src/hidapi/hidapi") ++ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${LIBUSB_CFLAGS} \"-I${SDL2_SOURCE_DIR}/src/hidapi/hidapi\"") + if(NOT HIDAPI_SKIP_LIBUSB) + set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/hidapi/libusb/hid.c) + list(APPEND EXTRA_LIBS ${LIBUSB_LIBS}) diff --git a/cmake/ports/sdl2/portfile.cmake b/cmake/ports/sdl2/portfile.cmake index c075c3403b..39ae733022 100644 --- a/cmake/ports/sdl2/portfile.cmake +++ b/cmake/ports/sdl2/portfile.cmake @@ -11,6 +11,7 @@ vcpkg_from_github( enable-winrt-cmake.patch fix-arm64-headers.patch disable-hidapi-for-uwp.patch + fix-space-in-path.patch ) string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" SDL_STATIC) diff --git a/cmake/ports/sranipal/portfile.cmake b/cmake/ports/sranipal/portfile.cmake index f71271d780..da4646be1a 100644 --- a/cmake/ports/sranipal/portfile.cmake +++ b/cmake/ports/sranipal/portfile.cmake @@ -5,7 +5,7 @@ set(MASTER_COPY_SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src) if (WIN32) vcpkg_download_distfile( SRANIPAL_SOURCE_ARCHIVE - URLS https://hifi-public.s3.amazonaws.com/seth/sranipal-1.1.0.1-windows.zip + URLS https://athena-public.s3.amazonaws.com/seth/sranipal-1.1.0.1-windows.zip SHA512 b09ce012abe4e3c71e8e69626bdd7823ff6576601a821ab365275f2764406a3e5f7b65fcf2eb1d0962eff31eb5958a148b00901f67c229dc6ace56eb5e6c9e1b FILENAME sranipal-1.1.0.1-windows.zip ) diff --git a/cmake/ports/tbb/portfile.cmake b/cmake/ports/tbb/portfile.cmake index 1d543b317e..4e81df37d1 100644 --- a/cmake/ports/tbb/portfile.cmake +++ b/cmake/ports/tbb/portfile.cmake @@ -2,9 +2,9 @@ include(vcpkg_common_functions) vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO intel/tbb + REPO oneapi-src/oneTBB REF 4bdba61bafc6ba2d636f31564f1de5702d365cf7 - SHA512 0b00c9deefdac5dc1f4fbae314e91eb3513b54b47ff6dec08ed2460486fc7d211ab36d6130e5787bfd50523cb613c65f03f9217d967292ca9056e2d3f5010bf8 + SHA512 f2a8d7e0476f846039390f4a79af3fe13770e23b01bf4741e738136f7ddb401357a0e50f35212e8d0fa5fc4cf1563418337309227d7243fc3676edd406ae652d HEAD_REF tbb_2019 PATCHES fix-static-build.patch ) diff --git a/cmake/ports/vhacd/portfile.cmake b/cmake/ports/vhacd/portfile.cmake index db41fe59f2..02d90cab18 100644 --- a/cmake/ports/vhacd/portfile.cmake +++ b/cmake/ports/vhacd/portfile.cmake @@ -4,7 +4,7 @@ vcpkg_check_linkage(ONLY_STATIC_LIBRARY) # else Linux desktop vcpkg_download_distfile( SOURCE_ARCHIVE - URLS https://public.highfidelity.com/dependencies/v-hacd-master.zip + URLS https://athena-public.s3.amazonaws.com/dependencies/v-hacd-master.zip SHA512 5d9bd4872ead9eb3574e4806d6c4f490353a04036fd5f571e1e44f47cb66b709e311abcd53af30bae0015a690152170aeed93209a626c28ebcfd6591f3bb036f FILENAME vhacd.zip ) diff --git a/cmake/ports/webrtc/portfile.cmake b/cmake/ports/webrtc/portfile.cmake index b5b46723bd..fdc653d6a5 100644 --- a/cmake/ports/webrtc/portfile.cmake +++ b/cmake/ports/webrtc/portfile.cmake @@ -2,19 +2,21 @@ include(vcpkg_common_functions) set(WEBRTC_VERSION 20190626) set(MASTER_COPY_SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src) +file(READ "${VCPKG_ROOT_DIR}/_env/EXTERNAL_BUILD_ASSETS.txt" EXTERNAL_BUILD_ASSETS) + if (ANDROID) # this is handled by hifi_android.py elseif (WIN32) vcpkg_download_distfile( WEBRTC_SOURCE_ARCHIVE - URLS https://hifi-public.s3.amazonaws.com/seth/webrtc-20190626-windows.zip + URLS "${EXTERNAL_BUILD_ASSETS}/seth/webrtc-20190626-windows.zip" SHA512 c0848eddb1579b3bb0496b8785e24f30470f3c477145035fd729264a326a467b9467ae9f426aa5d72d168ad9e9bf2c279150744832736bdf39064d24b04de1a3 FILENAME webrtc-20190626-windows.zip ) elseif (APPLE) vcpkg_download_distfile( WEBRTC_SOURCE_ARCHIVE - URLS https://hifi-public.s3.amazonaws.com/seth/webrtc-m78-osx.tar.gz + URLS "${EXTERNAL_BUILD_ASSETS}/seth/webrtc-m78-osx.tar.gz" SHA512 8b547da921cc96f5c22b4253a1c9e707971bb627898fbdb6b238ef1318c7d2512e878344885c936d4bd6a66005cc5b63dfc3fa5ddd14f17f378dcaa17b5e25df FILENAME webrtc-m78-osx.tar.gz ) @@ -22,7 +24,7 @@ else () # else Linux desktop vcpkg_download_distfile( WEBRTC_SOURCE_ARCHIVE - URLS https://hifi-public.s3.amazonaws.com/seth/webrtc-20190626-linux.tar.gz + URLS "${EXTERNAL_BUILD_ASSETS}/seth/webrtc-20190626-linux.tar.gz" SHA512 07d7776551aa78cb09a3ef088a8dee7762735c168c243053b262083d90a1d258cec66dc386f6903da5c4461921a3c2db157a1ee106a2b47e7756cb424b66cc43 FILENAME webrtc-20190626-linux.tar.gz ) diff --git a/cmake/templates/NSIS.template.in b/cmake/templates/NSIS.template.in index 9af99f927d..0e4c2f3579 100644 --- a/cmake/templates/NSIS.template.in +++ b/cmake/templates/NSIS.template.in @@ -161,7 +161,7 @@ ;General ; hide install details since we show an image slideshow in their place - ShowInstDetails nevershow + ShowInstDetails hide ; leverage the UAC NSIS plugin to promote uninstaller to elevated privileges !include UAC.nsh @@ -199,15 +199,18 @@ !system "$%TEMP%\tempinstaller.exe" = 2 + ; NOTE: We're not code signing right now, so we're going to disable that. + ; TODO: Get a code signing certificate so we can re-enable code signing. + ; The Inner invocation has written an uninstaller binary for us. ; We need to sign it if it's a production or PR build. - !if @PRODUCTION_BUILD@ == 1 - !if @BYPASS_SIGNING@ == 1 - !warning "BYPASS_SIGNING set - installer will not be signed" - !else - !system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0 - !endif - !endif + ; !if @PRODUCTION_BUILD@ == 1 + ; !if @BYPASS_SIGNING@ == 1 + ; !warning "BYPASS_SIGNING set - installer will not be signed" + ; !else + ; !system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0 + ; !endif + ; !endif ; Good. Now we can carry on writing the real installer. @@ -421,7 +424,7 @@ Function GetCampaignName Pop $0 ; Discard Path Pop $0 ; Recover filename ; Parse campaign out of the filename - ${RECaptureMatches} $0 "HighFidelity-([^-]*-)Beta-.*" $0 0 + ${RECaptureMatches} $0 "ProjectAthena-([^-]*-)Alpha-.*" $0 0 ${If} $0 == 1 Pop $0 ; Recover campaign name StrCpy $0 $0 -1 0 ; Remove trailing - and copy to _RetVar @@ -528,7 +531,7 @@ Var GAClientID Page custom PostInstallOptionsPage ReadPostInstallOptions !define MUI_PAGE_CUSTOMFUNCTION_PRE PageInstallFilesPre - !define MUI_PAGE_CUSTOMFUNCTION_SHOW StartInstallSlideshow + ; !define MUI_PAGE_CUSTOMFUNCTION_SHOW StartInstallSlideshow !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_UNPAGE_CONFIRM @@ -652,35 +655,35 @@ Var Express Function OnUserAbort !insertmacro LogStep "Installer" "Abort" "User Abort" "" - !insertmacro GoogleAnalytics "Installer" "Abort" "User Abort" "" + ; !insertmacro GoogleAnalytics "Installer" "Abort" "User Abort" "" FunctionEnd Function PageWelcomePre !insertmacro LogStep "Installer" "Welcome" "" "" - !insertmacro GoogleAnalytics "Installer" "Welcome" "" "" - !insertmacro DownloadSlideshowImages + ; !insertmacro GoogleAnalytics "Installer" "Welcome" "" "" + ; !insertmacro DownloadSlideshowImages FunctionEnd Function PageLicensePre !insertmacro LogStep "Installer" "License" "" "" - !insertmacro GoogleAnalytics "Installer" "License" "" "" + ; !insertmacro GoogleAnalytics "Installer" "License" "" "" FunctionEnd Function PageDirectoryPre !insertmacro MaybeSkipPage !insertmacro LogStep "Installer" "Directory" "" "" - !insertmacro GoogleAnalytics "Installer" "Directory" "" "" + ; !insertmacro GoogleAnalytics "Installer" "Directory" "" "" FunctionEnd Function PageStartMenuPre !insertmacro MaybeSkipPage !insertmacro LogStep "Installer" "StartMenu" "" "" - !insertmacro GoogleAnalytics "Installer" "StartMenu" "" "" + ; !insertmacro GoogleAnalytics "Installer" "StartMenu" "" "" FunctionEnd Function PageComponentsPre !insertmacro MaybeSkipPage !insertmacro LogStep "Installer" "Components" "" "" - !insertmacro GoogleAnalytics "Installer" "Components" "" "" + ; !insertmacro GoogleAnalytics "Installer" "Components" "" "" FunctionEnd Function PageInstallFilesPre !insertmacro LogStep "Installer" "Install" "" "" - !insertmacro GoogleAnalytics "Installer" "Install" "" "" + ; !insertmacro GoogleAnalytics "Installer" "Install" "" "" FunctionEnd !macro SetInstallOption Checkbox OptionName Default @@ -702,7 +705,7 @@ FunctionEnd Function InstallTypesPage !insertmacro LogStep "Installer" "Install Types" "" "" - !insertmacro GoogleAnalytics "Installer" "Install Types" "" "" + ; !insertmacro GoogleAnalytics "Installer" "Install Types" "" "" !insertmacro MUI_HEADER_TEXT "Choose Installation Type" "Express or Custom Install" @@ -717,7 +720,7 @@ Function InstallTypesPage StrCpy $OffsetUnits u StrCpy $Express "0" - ${NSD_CreateRadioButton} 30% $CurrentOffset$OffsetUnits 100% 10u "Express Install (Recommended)"; $\nInstalls High Fidelity Interface and High Fidelity Sandbox" + ${NSD_CreateRadioButton} 30% $CurrentOffset$OffsetUnits 100% 10u "Express Install (Recommended)"; $\nInstalls Project Athena Interface and Project Athena Sandbox" pop $ExpressInstallRadioButton ${NSD_OnClick} $ExpressInstallRadioButton ChangeExpressLabel IntOp $CurrentOffset $CurrentOffset + 15 @@ -813,7 +816,7 @@ Function PostInstallOptionsPage !insertmacro MaybeSkipPage !insertmacro LogStep "Installer" "Post Install Options" "" "" - !insertmacro GoogleAnalytics "Installer" "Post Install Options" "" "" + ; !insertmacro GoogleAnalytics "Installer" "Post Install Options" "" "" !insertmacro MUI_HEADER_TEXT "Setup Options" "" @@ -970,7 +973,7 @@ Function ReadPostInstallOptions ${If} @CLIENT_COMPONENT_CONDITIONAL@ ${LogText} "Option: Install Client" - ; check if the user asked for a desktop shortcut to High Fidelity + ; check if the user asked for a desktop shortcut to Project Athena ${NSD_GetState} $DesktopClientCheckbox $DesktopClientState ${LogText} "Option: Create Client Desktop Shortcut: $DesktopClientState" ${EndIf} @@ -1024,7 +1027,7 @@ Function HandlePostInstallOptions ${EndIf} ${If} @CLIENT_COMPONENT_CONDITIONAL@ - ; check if the user asked for a desktop shortcut to High Fidelity + ; check if the user asked for a desktop shortcut to Project Athena ${If} $DesktopClientState == ${BST_CHECKED} CreateShortCut "$DESKTOP\@INTERFACE_HF_SHORTCUT_NAME@.lnk" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@" !insertmacro WriteInstallOption "@CLIENT_DESKTOP_SHORTCUT_REG_KEY@" YES @@ -1085,7 +1088,7 @@ Function HandlePostInstallOptions ClearErrors ; copy the data from production build to this PR build - CopyFiles "$APPDATA\High Fidelity\*" $0 + CopyFiles "$APPDATA\Project Athena\*" $0 ; handle an error in copying files IfErrors 0 NoError @@ -1325,13 +1328,13 @@ Section "-Core installation" @CPACK_NSIS_EXTRA_INSTALL_COMMANDS@ ; see if we have a campaign that we might need to grab special content for - Call OptionallyDownloadCampaignServerless + ; Call OptionallyDownloadCampaignServerless ; Handle whichever post install options were set Call HandlePostInstallOptions !insertmacro LogStep "Installer" "Done" "" "" - !insertmacro GoogleAnalytics "Installer" "Done" "" "" + ; !insertmacro GoogleAnalytics "Installer" "Done" "" "" SectionEnd !include nsProcess.nsh @@ -1358,7 +1361,7 @@ SectionEnd /SD IDCANCEL IDRETRY Prompt_${UniqueID} IDCANCEL 0 ${EndIf} - !insertmacro GoogleAnalytics "Installer" "Abort" "${displayName} Running" "" + ; !insertmacro GoogleAnalytics "Installer" "Abort" "${displayName} Running" "" ; If the user decided to cancel, stop the current installer/uninstaller Abort @@ -1602,7 +1605,7 @@ Function .onInit !insertmacro InitGAClientID !insertmacro GetCampaignName $CampaignName - !insertmacro GoogleAnalytics "Installer" "Start" "$CampaignName" "" + ; !insertmacro GoogleAnalytics "Installer" "Start" "$CampaignName" "" ; make sure none of the installed applications are still running ${LogText} "Checking For Running Applications" diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index b854955953..cdf92918c6 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1227,8 +1227,8 @@ "name": "codec_preference_order", "label": "Audio Codec Preference Order", "help": "List of codec names in order of preferred usage", - "placeholder": "hifiAC, zlib, pcm", - "default": "hifiAC,zlib,pcm", + "placeholder": "opus, hifiAC, zlib, pcm", + "default": "opus,hifiAC,zlib,pcm", "advanced": true } ] diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c2de9c78ce..9fea49d2da 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -121,7 +122,7 @@ bool DomainServer::forwardMetaverseAPIRequest(HTTPConnection* connection, root.insert(requestSubobjectKey, subobject); QJsonDocument doc { root }; - QUrl url { NetworkingConstants::METAVERSE_SERVER_URL().toString() + metaversePath }; + QUrl url{ MetaverseAPI::getCurrentMetaverseServerURL().toString() + metaversePath }; QNetworkRequest req(url); req.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); @@ -516,7 +517,7 @@ bool DomainServer::optionallySetupOAuth() { // if we don't have an oauth provider URL then we default to the default node auth url if (_oauthProviderURL.isEmpty()) { - _oauthProviderURL = NetworkingConstants::METAVERSE_SERVER_URL(); + _oauthProviderURL = MetaverseAPI::getCurrentMetaverseServerURL(); } _oauthClientSecret = QProcessEnvironment::systemEnvironment().value(OAUTH_CLIENT_SECRET_ENV); @@ -2223,7 +2224,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url return true; } else if (url.path() == URI_API_METAVERSE_INFO) { QJsonObject rootJSON { - { "metaverse_url", NetworkingConstants::METAVERSE_SERVER_URL().toString() } + { "metaverse_url", MetaverseAPI::getCurrentMetaverseServerURL().toString() } }; QJsonDocument docJSON{ rootJSON }; @@ -2450,7 +2451,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url QJsonDocument doc(root); - QUrl url { NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/api/v1/places/" + place_id }; + QUrl url { MetaverseAPI::getCurrentMetaverseServerURL().toString() + "/api/v1/places/" + place_id }; url.setQuery("access_token=" + accessTokenVariant.toString()); diff --git a/hifi_qt.py b/hifi_qt.py index 2590ff8b78..6cae3bf59d 100644 --- a/hifi_qt.py +++ b/hifi_qt.py @@ -27,7 +27,9 @@ endif() def __init__(self, args): self.args = args self.configFilePath = os.path.join(args.build_root, 'qt.cmake') - self.version = '5.12.3' + self.version = os.getenv('VIRCADIA_USE_QT_VERSION', '5.12.3') + + self.assets_url = self.readVar('EXTERNAL_BUILD_ASSETS') defaultBasePath = os.path.expanduser('~/hifi/qt') self.basePath = os.getenv('HIFI_QT_BASE', defaultBasePath) @@ -45,23 +47,52 @@ endif() self.lockFile = os.path.join(lockDir, lockName) + if (os.getenv('VIRCADIA_USE_PREBUILT_QT')): + print("Using pre-built Qt5") + return + # OS dependent information system = platform.system() if 'Windows' == system: - self.qtUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows3.tar.gz?versionId=5ADqP0M0j5ZfimUHrx4zJld6vYceHEsI' + self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-windows3.tar.gz%3FversionId=5ADqP0M0j5ZfimUHrx4zJld6vYceHEsI' elif 'Darwin' == system: - self.qtUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz?versionId=bLAgnoJ8IMKpqv8NFDcAu8hsyQy3Rwwz' + self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz%3FversionId=bLAgnoJ8IMKpqv8NFDcAu8hsyQy3Rwwz' elif 'Linux' == system: - if platform.linux_distribution()[1][:3] == '16.': - self.qtUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz' - elif platform.linux_distribution()[1][:3] == '18.': - self.qtUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz' + import distro + dist = distro.linux_distribution() + + if distro.id() == 'ubuntu': + u_major = int( distro.major_version() ) + u_minor = int( distro.minor_version() ) + + if u_major == 16: + self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz' + elif u_major == 18: + self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz' + elif u_major == 19 and u_minor == 10: + self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.12.6-ubuntu-19.10.tar.xz' + elif u_major > 18 and ( u_major != 19 and u_minor != 4): + print("We don't support " + distro.name(pretty=True) + " yet. Perhaps consider helping us out?") + raise Exception('UNSUPPORTED LINUX VERSION!!!') + else: + print("Sorry, " + distro.name(pretty=True) + " is old and won't be officially supported. Please consider upgrading."); + raise Exception('UNSUPPORTED LINUX VERSION!!!') else: + print("Sorry, " + distro.name(pretty=True) + " is not supported. Please consider helping us out.") + print("It's also possible to build Qt for your distribution, please see the documentation at:") + print("https://github.com/kasenvr/project-athena/tree/kasen/core/tools/qt-builder") raise Exception('UNKNOWN LINUX VERSION!!!') else: + print("System : " + platform.system()) + print("Architecture: " + platform.architecture()) + print("Machine : " + platform.machine()) raise Exception('UNKNOWN OPERATING SYSTEM!!!') + def readVar(self, var): + with open(os.path.join(self.args.build_root, '_env', var + ".txt")) as fp: + return fp.read() + def writeConfig(self): print("Writing cmake config to {}".format(self.configFilePath)) # Write out the configuration for use by CMake diff --git a/hifi_utils.py b/hifi_utils.py index f9c3d50492..3a49f6d52b 100644 --- a/hifi_utils.py +++ b/hifi_utils.py @@ -118,6 +118,6 @@ def downloadAndExtract(url, destPath, hash=None, hasher=hashlib.sha512(), isZip= zip.extractall(destPath) else: # Extract the archive - with tarfile.open(tempFileName, 'r:gz') as tgz: + with tarfile.open(tempFileName, 'r:*') as tgz: tgz.extractall(destPath) os.remove(tempFileName) diff --git a/hifi_vcpkg.py b/hifi_vcpkg.py index 34c1b13563..9846d386c4 100644 --- a/hifi_vcpkg.py +++ b/hifi_vcpkg.py @@ -9,6 +9,7 @@ import tempfile import json import xml.etree.ElementTree as ET import functools +from os import path print = functools.partial(print, flush=True) @@ -35,6 +36,8 @@ endif() self.sourcePortsPath = args.ports_path self.id = hifi_utils.hashFolder(self.sourcePortsPath)[:8] self.configFilePath = os.path.join(args.build_root, 'vcpkg.cmake') + self.assets_url = self.readVar('EXTERNAL_BUILD_ASSETS') + # The noClean flag indicates we're doing weird dependency maintenance stuff # i.e. we've got an explicit checkout of vcpkg and we don't want the script to # do stuff it might otherwise do. It typically indicates that we're using our @@ -80,23 +83,23 @@ endif() if 'Windows' == system: self.exe = os.path.join(self.path, 'vcpkg.exe') self.bootstrapCmds = [ os.path.join(self.path, 'bootstrap-vcpkg.bat') ] - self.vcpkgUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/builds/vcpkg-win32-client.zip?versionId=tSFzbw01VkkVFeRQ6YuAY4dro2HxJR9U' + self.vcpkgUrl = self.assets_url + '/dependencies/vcpkg/builds/vcpkg-win32-client.zip%3FversionId=tSFzbw01VkkVFeRQ6YuAY4dro2HxJR9U' self.vcpkgHash = 'a650db47a63ccdc9904b68ddd16af74772e7e78170b513ea8de5a3b47d032751a3b73dcc7526d88bcb500753ea3dd9880639ca842bb176e2bddb1710f9a58cd3' self.hostTriplet = 'x64-windows' if usePrebuilt: - self.prebuiltArchive = "https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/builds/vcpkg-win32.zip?versionId=3SF3mDC8dkQH1JP041m88xnYmWNzZflx" + self.prebuiltArchive = self.assets_url + "/dependencies/vcpkg/builds/vcpkg-win32.zip%3FversionId=3SF3mDC8dkQH1JP041m88xnYmWNzZflx" elif 'Darwin' == system: self.exe = os.path.join(self.path, 'vcpkg') self.bootstrapCmds = [ os.path.join(self.path, 'bootstrap-vcpkg.sh'), '--allowAppleClang' ] - self.vcpkgUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/builds/vcpkg-osx-client.tgz?versionId=j0b4azo_zTlH_Q9DElEWOz1UMYZ2nqQw' + self.vcpkgUrl = self.assets_url + '/dependencies/vcpkg/builds/vcpkg-osx-client.tgz%3FversionId=j0b4azo_zTlH_Q9DElEWOz1UMYZ2nqQw' self.vcpkgHash = '519d666d02ef22b87c793f016ca412e70f92e1d55953c8f9bd4ee40f6d9f78c1df01a6ee293907718f3bbf24075cc35492fb216326dfc50712a95858e9cbcb4d' self.hostTriplet = 'x64-osx' if usePrebuilt: - self.prebuiltArchive = "https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/builds/vcpkg-osx.tgz?versionId=6JrIMTdvpBF3MAsjA92BMkO79Psjzs6Z" + self.prebuiltArchive = self.assets_url + "/dependencies/vcpkg/builds/vcpkg-osx.tgz%3FversionId=6JrIMTdvpBF3MAsjA92BMkO79Psjzs6Z" else: self.exe = os.path.join(self.path, 'vcpkg') self.bootstrapCmds = [ os.path.join(self.path, 'bootstrap-vcpkg.sh') ] - self.vcpkgUrl = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/builds/vcpkg-linux-client.tgz?versionId=y7mct0gFicEXz5hJy3KROBugcLR56YWf' + self.vcpkgUrl = self.assets_url + '/dependencies/vcpkg/builds/vcpkg-linux-client.tgz%3FversionId=y7mct0gFicEXz5hJy3KROBugcLR56YWf' self.vcpkgHash = '6a1ce47ef6621e699a4627e8821ad32528c82fce62a6939d35b205da2d299aaa405b5f392df4a9e5343dd6a296516e341105fbb2dd8b48864781d129d7fba10d' self.hostTriplet = 'x64-linux' @@ -106,6 +109,14 @@ endif() else: self.triplet = self.hostTriplet + def readVar(self, var): + with open(os.path.join(self.args.build_root, '_env', var + ".txt")) as fp: + return fp.read() + + def writeVar(self, var, value): + with open(os.path.join(self.args.build_root, '_env', var + ".txt"), 'w') as fp: + fp.write(value) + def upToDate(self): # Prevent doing a clean if we've explcitly set a directory for vcpkg if self.noClean: @@ -127,6 +138,17 @@ endif() return False return True + def copyEnv(self): + print("Passing on variables to vcpkg") + srcEnv = os.path.join(self.args.build_root, "_env") + destEnv = os.path.join(self.path, "_env") + + if path.exists(destEnv): + shutil.rmtree(destEnv) + + shutil.copytree(srcEnv, destEnv) + + def clean(self): print("Cleaning vcpkg installation at {}".format(self.path)) if os.path.isdir(self.path): @@ -136,6 +158,7 @@ endif() # Make sure the VCPKG prerequisites are all there. def bootstrap(self): if self.upToDate(): + self.copyEnv() return if self.prebuiltArchive is not None: @@ -160,7 +183,7 @@ endif() if downloadVcpkg: if "HIFI_VCPKG_BOOTSTRAP" in os.environ: print("Cloning vcpkg from github to {}".format(self.path)) - hifi_utils.executeSubprocess(['git', 'clone', 'https://github.com/microsoft/vcpkg.git', self.path]) + hifi_utils.executeSubprocess(['git', 'clone', 'https://github.com/microsoft/vcpkg', self.path]) print("Bootstrapping vcpkg") hifi_utils.executeSubprocess(self.bootstrapCmds, folder=self.path, env=self.bootstrapEnv) else: @@ -174,6 +197,7 @@ endif() if (os.path.isdir(portsPath)): shutil.rmtree(portsPath, ignore_errors=True) shutil.copytree(self.sourcePortsPath, portsPath) + self.copyEnv() def run(self, commands): actualCommands = [self.exe, '--vcpkg-root', self.path] @@ -220,7 +244,7 @@ endif() # vcpkg prebuilt if not os.path.isdir(os.path.join(self.path, 'installed', 'arm64-android')): dest = os.path.join(self.path, 'installed') - url = "https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/vcpkg-arm64-android.tar.gz" + url = self.assets_url + "/dependencies/vcpkg/vcpkg-arm64-android.tar.gz" # FIXME I don't know why the hash check frequently fails here. If you examine the file later it has the right hash #hash = "832f82a4d090046bdec25d313e20f56ead45b54dd06eee3798c5c8cbdd64cce4067692b1c3f26a89afe6ff9917c10e4b601c118bea06d23f8adbfe5c0ec12bc3" #hifi_utils.downloadAndExtract(url, dest, hash) diff --git a/ice-server/src/IceServer.cpp b/ice-server/src/IceServer.cpp index 6896c7a9c9..2d601048be 100644 --- a/ice-server/src/IceServer.cpp +++ b/ice-server/src/IceServer.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -209,7 +210,7 @@ void IceServer::requestDomainPublicKey(const QUuid& domainID) { // send a request to the metaverse API for the public key for this domain auto& networkAccessManager = NetworkAccessManager::getInstance(); - QUrl publicKeyURL { NetworkingConstants::METAVERSE_SERVER_URL() }; + QUrl publicKeyURL{ MetaverseAPI::getCurrentMetaverseServerURL() }; QString publicKeyPath = QString("/api/v1/domains/%1/public_key").arg(uuidStringWithoutCurlyBraces(domainID)); publicKeyURL.setPath(publicKeyPath); diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 4dcb0778d4..dc9e5254df 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -142,6 +142,9 @@ if (APPLE) list(APPEND INTERFACE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}) endif() +if (UNIX) + set(BUILD_SHARED_LIBS ON) +endif () # create the executable, make it a bundle on OS X if (APPLE) @@ -156,12 +159,14 @@ elseif (WIN32) set(CONFIGURE_ICON_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Icon.rc") configure_file("${HF_CMAKE_DIR}/templates/Icon.rc.in" ${CONFIGURE_ICON_RC_OUTPUT}) - set(APP_FULL_NAME "High Fidelity") + set(APP_FULL_NAME "Project Athena") set(CONFIGURE_VERSION_INFO_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc") configure_file("${HF_CMAKE_DIR}/templates/VersionInfo.rc.in" ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) # add an executable that also has the icon itself and the configured rc file as resources add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) + ##^^^^^ creates native Win32 app w/o cmd console vvvvvv forces cmd console for logging + # add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT}) if (NOT DEV_BUILD) add_custom_command( diff --git a/interface/icon/interface-beta.icns b/interface/icon/interface-beta.icns index 8dadfd5037..1fe162f88e 100644 Binary files a/interface/icon/interface-beta.icns and b/interface/icon/interface-beta.icns differ diff --git a/interface/icon/interface-beta.ico b/interface/icon/interface-beta.ico index 09a97956a7..63a3eff482 100644 Binary files a/interface/icon/interface-beta.ico and b/interface/icon/interface-beta.ico differ diff --git a/interface/icon/interface.icns b/interface/icon/interface.icns index 8dadfd5037..1fe162f88e 100644 Binary files a/interface/icon/interface.icns and b/interface/icon/interface.icns differ diff --git a/interface/icon/interface.ico b/interface/icon/interface.ico index 09a97956a7..63a3eff482 100644 Binary files a/interface/icon/interface.ico and b/interface/icon/interface.ico differ diff --git a/interface/resources/html/img/tablet-help-gamepad.jpg b/interface/resources/html/img/tablet-help-gamepad.jpg index af44233537..3f246e5cc0 100644 Binary files a/interface/resources/html/img/tablet-help-gamepad.jpg and b/interface/resources/html/img/tablet-help-gamepad.jpg differ diff --git a/interface/resources/html/img/tablet-help-keyboard.jpg b/interface/resources/html/img/tablet-help-keyboard.jpg index 5c4a3e37ef..ec4c0ec60d 100644 Binary files a/interface/resources/html/img/tablet-help-keyboard.jpg and b/interface/resources/html/img/tablet-help-keyboard.jpg differ diff --git a/interface/resources/html/img/tablet-help-oculus.jpg b/interface/resources/html/img/tablet-help-oculus.jpg index 1b2a4f4198..64b57aaccb 100644 Binary files a/interface/resources/html/img/tablet-help-oculus.jpg and b/interface/resources/html/img/tablet-help-oculus.jpg differ diff --git a/interface/resources/html/img/tablet-help-vive.jpg b/interface/resources/html/img/tablet-help-vive.jpg index 9e8cca69fe..75ccf601e2 100644 Binary files a/interface/resources/html/img/tablet-help-vive.jpg and b/interface/resources/html/img/tablet-help-vive.jpg differ diff --git a/interface/resources/html/img/tablet-help-windowsMR.jpg b/interface/resources/html/img/tablet-help-windowsMR.jpg index f35c88e35b..848e3deff6 100644 Binary files a/interface/resources/html/img/tablet-help-windowsMR.jpg and b/interface/resources/html/img/tablet-help-windowsMR.jpg differ diff --git a/interface/resources/html/tabletHelp.html b/interface/resources/html/tabletHelp.html index e83c0cc388..a414417239 100644 --- a/interface/resources/html/tabletHelp.html +++ b/interface/resources/html/tabletHelp.html @@ -77,13 +77,13 @@ var handControllerImageURL = null; var index = 0; var count = 3; - var handControllerRefURL = "https://docs.highfidelity.com/explore/get-started/vr-controls.html#vr-controls"; - var keyboardRefURL = "https://docs.highfidelity.com/explore/get-started/desktop.html#movement-controls"; - var gamepadRefURL = "https://docs.highfidelity.com/explore/get-started/vr-controls.html#gamepad"; + var handControllerRefURL = "https://docs.projectathena.dev/explore/get-started/vr-controls.html#vr-controls"; + var keyboardRefURL = "https://docs.projectathena.dev/explore/get-started/desktop.html#movement-controls"; + var gamepadRefURL = "https://docs.projectathena.dev/explore/get-started/vr-controls.html#gamepad"; function showKbm() { document.getElementById("main_image").setAttribute("src", "img/tablet-help-keyboard.jpg"); - document.getElementById("image_button").setAttribute("href", keyboardRefURL); + document.getElementById("image_button").setAttribute("href", keyboardRefURL); } function showHandControllers() { @@ -189,7 +189,7 @@ - Report Problem + Report Problem diff --git a/interface/resources/images/Loading-Inner-H.png b/interface/resources/images/Loading-Inner-H.png index cf09ea8317..93369d61c8 100644 Binary files a/interface/resources/images/Loading-Inner-H.png and b/interface/resources/images/Loading-Inner-H.png differ diff --git a/interface/resources/images/about-opus.png b/interface/resources/images/about-opus.png new file mode 100644 index 0000000000..57924b070f Binary files /dev/null and b/interface/resources/images/about-opus.png differ diff --git a/interface/resources/images/about-projectathena.png b/interface/resources/images/about-projectathena.png new file mode 100644 index 0000000000..ae2d2bcd06 Binary files /dev/null and b/interface/resources/images/about-projectathena.png differ diff --git a/interface/resources/images/project-athena-banner-color2.svg b/interface/resources/images/project-athena-banner-color2.svg new file mode 100644 index 0000000000..b41a980fe0 --- /dev/null +++ b/interface/resources/images/project-athena-banner-color2.svg @@ -0,0 +1,157 @@ + + + + + + image/svg+xml + + Artboard 1 + + + + + + + + + + + + + + + + + + + Artboard 1 + + + + + + + + + + + + + + + + + + + + + diff --git a/interface/resources/qml/+webengine/BrowserWebView.qml b/interface/resources/qml/+webengine/BrowserWebView.qml index 137531f517..7f2136ec4f 100644 --- a/interface/resources/qml/+webengine/BrowserWebView.qml +++ b/interface/resources/qml/+webengine/BrowserWebView.qml @@ -6,7 +6,7 @@ import controlsUit 1.0 WebView { id: webview - url: "https://highfidelity.com/" + url: "https://projectathena.io/" profile: FileTypeProfile; property var parentRoot: null diff --git a/interface/resources/qml/+webengine/QmlWebWindowView.qml b/interface/resources/qml/+webengine/QmlWebWindowView.qml index d2f1820e9a..84ab61ad28 100644 --- a/interface/resources/qml/+webengine/QmlWebWindowView.qml +++ b/interface/resources/qml/+webengine/QmlWebWindowView.qml @@ -40,7 +40,7 @@ Controls.WebView { userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard, userScript ] function onWebEventReceived(event) { - if (event.slice(0, 17) === "CLARA.IO DOWNLOAD") { + if (typeof event === "string" && event.slice(0, 17) === "CLARA.IO DOWNLOAD") { ApplicationInterface.addAssetToWorldFromURL(event.slice(18)); } } diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index e3cd492edb..fbc8f9495a 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -4,6 +4,7 @@ // Created by David Rowe on 3 Jun 2015 // Copyright 2015 High Fidelity, Inc. // Distributed under the Apache License, Version 2.0. +// // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // @@ -84,7 +85,7 @@ FocusScope { Image { id: banner anchors.centerIn: parent - source: "../images/high-fidelity-banner.svg" + source: "../images/project-athena-banner-color2.svg" horizontalAlignment: Image.AlignHCenter } } diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 6b98f2aef3..526d1da665 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -402,7 +402,7 @@ Item { font.pixelSize: linkAccountBody.textFieldFontSize font.bold: linkAccountBody.fontBold - text: " Can't access your account?" + text: " Can't access your account?" verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter @@ -527,7 +527,7 @@ Item { leftMargin: hifi.dimensions.contentSpacing.x } - text: "Sign Up" + text: "Sign Up" linkColor: hifi.colors.blueAccent onLinkActivated: { diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index f1e0cfe685..7347464f4e 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -23,7 +23,7 @@ Item { clip: true height: root.height width: root.width - readonly property string termsContainerText: qsTr("By signing up, you agree to High Fidelity's Terms of Service") + readonly property string termsContainerText: qsTr("By signing up, you agree to Project Athena's Terms of Service") property int textFieldHeight: 31 property string fontFamily: "Raleway" property int fontSize: 15 @@ -395,7 +395,7 @@ Item { text: signUpBody.termsContainerText Component.onCompleted: { // with the link. - termsText.text = qsTr("By signing up, you agree to High Fidelity's Terms of Service") + termsText.text = qsTr("By signing up, you agree to Project Athena's Terms of Service") } } diff --git a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml index d2fd1dfe35..8b3c878d46 100644 --- a/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml +++ b/interface/resources/qml/LoginDialog/UsernameCollisionBody.qml @@ -19,7 +19,7 @@ import TabletScriptingInterface 1.0 Item { id: usernameCollisionBody clip: true - readonly property string termsContainerText: qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") + readonly property string termsContainerText: qsTr("By creating this user profile, you agree to Project Athena's Terms of Service") width: root.width height: root.height readonly property string fontFamily: "Raleway" @@ -218,7 +218,7 @@ Item { text: usernameCollisionBody.termsContainerText Component.onCompleted: { // with the link. - termsText.text = qsTr("By creating this user profile, you agree to High Fidelity's Terms of Service") + termsText.text = qsTr("By creating this user profile, you agree to Project Athena's Terms of Service") } } diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index b01bb5b761..a7e5c236ca 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -129,7 +129,7 @@ FocusScope { Image { id: banner anchors.centerIn: parent - source: "../../images/high-fidelity-banner.svg" + source: "../../images/project-athena-banner-color2.svg" horizontalAlignment: Image.AlignHCenter } } diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index eef339b854..963a3246fc 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -44,7 +44,6 @@ Rectangle { return (root.parent !== null) && root.parent.objectName == "loader"; } - property bool isVR: AudioScriptingInterface.context === "VR" property real rightMostInputLevelPos: root.width //placeholder for control sizes and paddings @@ -128,16 +127,16 @@ Rectangle { anchors.top: flickView.top; anchors.right: flickView.right; anchors.bottom: flickView.bottom; - anchors.rightMargin: -verticalScrollWidth; //compensate flickView's right margin + z: 100 // Display over top of separators. + background: Item { implicitWidth: verticalScrollWidth; Rectangle { - color: hifi.colors.darkGray30; + color: hifi.colors.baseGrayShadow radius: 4; anchors { fill: parent; - topMargin: -1; // Finesse size - bottomMargin: -2; + topMargin: 2 // Finess position } } } @@ -148,9 +147,7 @@ Rectangle { color: hifi.colors.white30; anchors { fill: parent; - leftMargin: 2; // Finesse size and position. - topMargin: 1; - bottomMargin: 1; + topMargin: 1; // Finesse position. } } } @@ -338,7 +335,6 @@ Rectangle { anchors.topMargin: 10; } - Item { id: inputDeviceHeader x: margins.paddings; @@ -688,4 +684,5 @@ Rectangle { anchors.topMargin: 10; } } + } diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml index 31528a8557..edb862b023 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml @@ -128,6 +128,8 @@ ShadowRectangle { } } + // FIXME: Link to a Project Athena version of the video. + /* RalewayButton { id: video visible: false @@ -141,6 +143,12 @@ ShadowRectangle { onClicked: videoButtonClicked() } + */ + // Temporary placeholder for video button. + Rectangle { + id: video + visible: false + } RalewayButton { id: docs diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml index 5dd2dd0bd6..a0c98b0821 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml @@ -44,7 +44,11 @@ Item { HifiControls.Button { id: uploadButton + // FIXME: Re-enable if ability to upload to hosted location is added. + /* visible: AvatarPackagerCore.currentAvatarProject && !AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded + */ + visible: false enabled: Account.loggedIn anchors.verticalCenter: parent.verticalCenter @@ -62,7 +66,11 @@ Item { HifiControls.Button { id: updateButton + // FIXME: Re-enable if ability to upload to hosted location is added. + /* visible: AvatarPackagerCore.currentAvatarProject && AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded + */ + visible: false enabled: Account.loggedIn anchors.verticalCenter: parent.verticalCenter @@ -79,7 +87,12 @@ Item { } Item { anchors.fill: parent + + // FIXME: Re-enable if ability to upload to hosted location is added. + /* visible: root.hasSuccessfullyUploaded + */ + visible: false; HifiControls.Button { enabled: Account.loggedIn @@ -115,6 +128,22 @@ Item { onClicked: AvatarPackagerCore.currentAvatarProject.openInInventory() } } + // FIXME: Remove if "Upload" button is reinstated. + HifiControls.Button { + id: openDirectoryButton + visible: AvatarPackagerCore.currentAvatarProject + enabled: true + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + text: qsTr("Open Project Folder") + color: hifi.buttons.blue + colorScheme: root.colorScheme + width: 200 + height: 40 + onClicked: { + fileDialogHelper.openDirectory(fileDialogHelper.pathToUrl(AvatarPackagerCore.currentAvatarProject.projectFolderPath)); + } + } } Rectangle { @@ -263,13 +292,58 @@ Item { color: 'white' size: 20 - anchors.left: parent.left - anchors.right: parent.right + anchors.horizontalCenter: parent.horizontalCenter anchors.top: errorsGlyph.bottom wrapMode: Text.Wrap } + RalewayRegular { + id: notForSaleMessage + + visible: root.hasSuccessfullyUploaded + + color: 'white' + linkColor: '#00B4EF' + size: 20 + + anchors.left: parent.left + anchors.right: parent.right + anchors.top: doctorStatusMessage.bottom + anchors.topMargin: 10 + + anchors.bottomMargin: 24 + + wrapMode: Text.Wrap + text: "This item is not for sale yet, learn more." + + onLinkActivated: { + Qt.openUrlExternally("https://docs.projectathena.dev/sell/add-item/upload-avatar.html"); + } + } + + RalewayRegular { + id: showErrorsLink + + color: 'white' + linkColor: '#00B4EF' + + visible: AvatarPackagerCore.currentAvatarProject && AvatarPackagerCore.currentAvatarProject.hasErrors + + anchors { + top: notForSaleMessage.bottom + horizontalCenter: parent.horizontalCenter + } + + size: 28 + + text: "View all errors" + + onLinkActivated: { + avatarPackager.state = AvatarPackagerState.avatarDoctorErrorReport; + } + } + RalewayRegular { id: infoMessage @@ -297,60 +371,14 @@ Item { anchors.left: parent.left anchors.right: parent.right - anchors.top: doctorStatusMessage.bottom - + anchors.bottom: showFilesText.top anchors.bottomMargin: 24 wrapMode: Text.Wrap - text: "You can upload your files to our servers to always access them, and to make your avatar visible to other users." - } - - RalewayRegular { - id: notForSaleMessage - - visible: root.hasSuccessfullyUploaded - - color: 'white' - linkColor: '#00B4EF' - size: 20 - - anchors.left: parent.left - anchors.right: parent.right - anchors.top: infoMessage.bottom - anchors.topMargin: 10 - - anchors.bottomMargin: 24 - - wrapMode: Text.Wrap - text: "This item is not for sale yet, learn more." - - onLinkActivated: { - Qt.openUrlExternally("https://docs.projectathena.dev/sell/add-item/upload-avatar.html"); - } - } - - RalewayRegular { - id: showErrorsLink - - color: 'white' - linkColor: '#00B4EF' - - visible: AvatarPackagerCore.currentAvatarProject && AvatarPackagerCore.currentAvatarProject.hasErrors - - anchors { - top: notForSaleMessage.visible ? notForSaleMessage.bottom : infoMessage .bottom - bottom: showFilesText.top - horizontalCenter: parent.horizontalCenter - } - - size: 28 - - text: "View all errors" - - onLinkActivated: { - avatarPackager.state = AvatarPackagerState.avatarDoctorErrorReport; - } + // FIXME: Restore original text if ability to upload to hosted location is added. + //text: "You can upload your files to our servers to always access them, and to make your avatar visible to other users." + text: "Your files are ready to be uploaded to a server to make your avatar visible to other users." } HifiControls.Button { @@ -389,8 +417,13 @@ Item { Rectangle { id: loginRequiredMessage + // FIXME: Re-enable if ability to upload to hosted location is added. + /* visible: !Account.loggedIn height: !Account.loggedIn ? loginRequiredTextRow.height + 20 : 0 + */ + visible: false + height: 0 anchors { bottom: parent.bottom diff --git a/interface/resources/qml/hifi/avatarapp/AvatarsModel.qml b/interface/resources/qml/hifi/avatarapp/AvatarsModel.qml index bfd66f1a30..012cfc3b79 100644 --- a/interface/resources/qml/hifi/avatarapp/AvatarsModel.qml +++ b/interface/resources/qml/hifi/avatarapp/AvatarsModel.qml @@ -21,17 +21,47 @@ ListModel { return marketItemUrl; } + + function makeMarketThumbnailUrl(marketId) { + var avatarThumbnailUrl = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/%marketId%/large/hifi-mp-%marketId%.jpg" + .split('%marketId%').join(marketId); + + return avatarThumbnailUrl; + } + + function trimFileExtension(url) { + var trimmedUrl = url.substring(0, (url.indexOf("#") === -1) ? url.length : url.indexOf("#")); + trimmedUrl = trimmedUrl.substring(0, (trimmedUrl.indexOf("?") === -1) ? trimmedUrl.length : trimmedUrl.indexOf("?")); + trimmedUrl = trimmedUrl.substring(0, trimmedUrl.lastIndexOf(".")); + + return trimmedUrl; + } + + function imageExists(imageUrl) { + + var http = new XMLHttpRequest(); + + http.open('HEAD', imageUrl, false); + http.send(); + + return http.status !== 404; + + } function makeThumbnailUrl(avatarUrl) { var marketId = extractMarketId(avatarUrl); - if (marketId === '') { + if (marketId !== '') { + return makeMarketThumbnailUrl(marketId); + } + + var avatarThumbnailFileUrl = trimFileExtension(avatarUrl) + ".jpg"; + var thumbnailExist = imageExists(avatarThumbnailFileUrl); + + if (!thumbnailExist) { return ''; } - - var avatarThumbnailUrl = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/previews/%marketId%/large/hifi-mp-%marketId%.jpg" - .split('%marketId%').join(marketId); - - return avatarThumbnailUrl; + + return avatarThumbnailFileUrl; } function makeAvatarObject(avatar, avatarName) { diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 315fc540dd..b1b367f2b2 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -778,7 +778,7 @@ Rectangle { lightboxPopup.bodyText = "Rezzing this content set will replace the existing environment and all of the items in this domain. " + "If you want to save the state of the content in this domain, create a backup before proceeding.

" + "For more information about backing up and restoring content, " + - "" + + "" + "click here to open info on your desktop browser."; lightboxPopup.button1text = "CANCEL"; lightboxPopup.button1method = function() { diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 40365ef9e7..66113985e8 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -602,7 +602,7 @@ Rectangle { lightboxPopup.bodyText = "Rezzing this content set will replace the existing environment and all of the items in this domain. " + "If you want to save the state of the content in this domain, create a backup before proceeding.

" + "For more information about backing up and restoring content, " + - "
" + + "" + "click here to open info on your desktop browser."; lightboxPopup.button1text = "CANCEL"; lightboxPopup.button1method = function() { diff --git a/interface/resources/qml/hifi/commerce/wallet/Help.qml b/interface/resources/qml/hifi/commerce/wallet/Help.qml index 1cf72490e1..af1e1b5ab9 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Help.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Help.qml @@ -207,7 +207,7 @@ At the moment, there is currently no way to convert HFC to other currencies. Sta if (link === "#privateKeyPath") { Qt.openUrlExternally("file:///" + root.keyFilePath.substring(0, root.keyFilePath.lastIndexOf('/'))); } else if (link === "#blockchain") { - Qt.openUrlExternally("https://docs.highfidelity.com/high-fidelity-commerce"); + Qt.openUrlExternally("https://docs.projectathena.dev/explore/shop.html"); } else if (link === "#bank") { if ((Account.metaverseServerURL).toString().indexOf("staging") >= 0) { Qt.openUrlExternally("hifi://hifiqa-master-metaverse-staging"); // So that we can test in staging. diff --git a/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml index 87f307b9bc..2be66442ce 100644 --- a/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml +++ b/interface/resources/qml/hifi/dialogs/TabletAboutDialog.qml @@ -25,7 +25,7 @@ Rectangle { Image { sourceSize.width: 295 sourceSize.height: 75 - source: "../../../images/about-highfidelity.png" + source: "../../../images/about-projectathena.png" } Item { height: 30; width: 1 } Column { @@ -45,7 +45,7 @@ Rectangle { } Item { height: 10; width: 1 } RalewayRegular { - text: "An open-source virtual reality platform." + text: "An open source virtual reality platform." size: 20 color: "white" } @@ -53,11 +53,12 @@ Rectangle { textFormat: Text.StyledText linkColor: "#00B4EF" color: "white" - text: "www.highfidelity.com." + text: "Project Athena Github." size: 20 onLinkActivated: { - HiFiAbout.openUrl("https:/www.highfidelity.com"); + HiFiAbout.openUrl("https:/github.com/kasenvr/project-athena"); } + } Item { height: 40; width: 1 } Row { @@ -92,21 +93,35 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter } } + Row { + spacing: 5 + Image { + sourceSize.width: 34 + sourceSize.height: 25 + source: "../../../images/about-opus.png" + MouseArea { + anchors.fill: parent + onClicked: { + HiFiAbout.openUrl("http://opus-codec.org/"); + } + } + } + RalewayRegular { + color: "white" + text: "Built using the Opus codec." + size: 12 + anchors.verticalCenter: parent.verticalCenter + } + } Item { height: 20; width: 1 } RalewayRegular { - textFormat: Text.StyledText - linkColor: "#00B4EF" color: "white" - property string link: "https://eos.io/" - text: "Blockchain technology from EOS." + text: "© 2019 - 2020 Project Athena Contributors." size: 14 - onLinkActivated: { - HiFiAbout.openUrl(link); - } } RalewayRegular { color: "white" - text: "© 2012 - 2019 High Fidelity, Inc.. All rights reserved." + text: "© 2012 - 2019 High Fidelity, Inc. All rights reserved." size: 14 } RalewayRegular { diff --git a/interface/resources/qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml b/interface/resources/qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml new file mode 100644 index 0000000000..9e0b6ba4cf --- /dev/null +++ b/interface/resources/qml/hifi/dialogs/security/EntityScriptQMLWhitelist.qml @@ -0,0 +1,206 @@ +// +// EntityScriptQMLWhitelist.qml +// interface/resources/qml/hifi/dialogs/security +// +// Created by Kasen IO on 2019.12.05 | realities.dev | kasenvr@gmail.com +// Copyright 2019 Kasen IO +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// Security Settings for the Entity Script QML Whitelist + +import Hifi 1.0 as Hifi +import QtQuick 2.8 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.12 +import stylesUit 1.0 as HifiStylesUit +import controlsUit 1.0 as HiFiControls +import PerformanceEnums 1.0 +import "../../../windows" + + +Rectangle { + id: parentBody; + + function getWhitelistAsText() { + var whitelist = Settings.getValue("private/settingsSafeURLS"); + var arrayWhitelist = whitelist.split(",").join("\n"); + return arrayWhitelist; + } + + function setWhitelistAsText(whitelistText) { + Settings.setValue("private/settingsSafeURLS", whitelistText.text); + + var originalSetString = whitelistText.text; + var originalSet = originalSetString.split(' ').join(''); + + var check = Settings.getValue("private/settingsSafeURLS"); + var arrayCheck = check.split(",").join("\n"); + + setWhitelistSuccess(arrayCheck === originalSet); + } + + function setWhitelistSuccess(success) { + if (success) { + notificationText.text = "Successfully saved settings."; + } else { + notificationText.text = "Error! Settings not saved."; + } + } + + function toggleWhitelist(enabled) { + Settings.setValue("private/whitelistEnabled", enabled); + console.info("Toggling Whitelist to:", enabled); + } + + function initCheckbox() { + var check = Settings.getValue("private/whitelistEnabled", false); + + if (check) { + whitelistEnabled.toggle(); + } + } + + + anchors.fill: parent + width: parent.width; + height: 120; + color: "#80010203"; + + HifiStylesUit.RalewayRegular { + id: titleText; + text: "Entity Script / QML Whitelist" + // Text size + size: 24; + // Style + color: "white"; + elide: Text.ElideRight; + // Anchors + anchors.top: parent.top; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + height: 60; + + CheckBox { + Component.onCompleted: { + initCheckbox(); + } + + id: whitelistEnabled; + + anchors.right: parent.right; + anchors.top: parent.top; + anchors.topMargin: 10; + onToggled: { + toggleWhitelist(whitelistEnabled.checked) + } + + Label { + text: "Enabled" + color: "white" + font.pixelSize: 18; + anchors.right: parent.left; + anchors.top: parent.top; + anchors.topMargin: 10; + } + } + } + + Rectangle { + id: textAreaRectangle; + color: "black"; + width: parent.width; + height: 250; + anchors.top: titleText.bottom; + + ScrollView { + id: textAreaScrollView + anchors.fill: parent; + width: parent.width + height: parent.height + contentWidth: parent.width + contentHeight: parent.height + clip: false; + + TextArea { + id: whitelistTextArea + text: getWhitelistAsText(); + onTextChanged: notificationText.text = ""; + width: parent.width; + height: parent.height; + font.family: "Ubuntu"; + font.pointSize: 12; + color: "white"; + } + } + + Button { + id: saveChanges + anchors.topMargin: 5; + anchors.leftMargin: 20; + anchors.rightMargin: 20; + x: textAreaRectangle.x + textAreaRectangle.width - width - 15; + y: textAreaRectangle.y + textAreaRectangle.height - height; + contentItem: Text { + text: saveChanges.text + font.family: "Ubuntu"; + font.pointSize: 12; + opacity: enabled ? 1.0 : 0.3 + color: "black" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + text: "Save Changes" + onClicked: setWhitelistAsText(whitelistTextArea) + + HifiStylesUit.RalewayRegular { + id: notificationText; + text: "" + // Text size + size: 16; + // Style + color: "white"; + elide: Text.ElideLeft; + // Anchors + anchors.right: parent.left; + anchors.rightMargin: 10; + } + } + + HifiStylesUit.RalewayRegular { + id: descriptionText; + text: + "The whitelist checks scripts and QML as they are loaded.
+ Therefore, if a script is cached or has no reason to load again,
+ removing it from the whitelist will have no effect until
+ it is reloaded.
+ Separate your whitelisted domains by line, not commas. e.g. +
+ https://google.com/
+ hifi://the-spot/
+ 127.0.0.1
+ https://mydomain.here/ +
+ Ensure there are no spaces or whitespace.

+ For QML files, you can only whitelist each file individually
+ ending with '.qml'." + // Text size + size: 16; + // Style + color: "white"; + elide: Text.ElideRight; + textFormat: Text.RichText; + // Anchors + anchors.top: parent.bottom; + anchors.topMargin: 90; + anchors.left: parent.left; + anchors.leftMargin: 20; + anchors.right: parent.right; + anchors.rightMargin: 20; + } + } +} diff --git a/interface/resources/qml/hifi/tablet/TabletRoot.qml b/interface/resources/qml/hifi/tablet/TabletRoot.qml index 6001497743..2fa08428ae 100644 --- a/interface/resources/qml/hifi/tablet/TabletRoot.qml +++ b/interface/resources/qml/hifi/tablet/TabletRoot.qml @@ -200,7 +200,7 @@ Rectangle { id: eventBridgeConnection target: eventBridge onWebEventReceived: { - if (message.slice(0, 17) === "CLARA.IO DOWNLOAD") { + if (typeof message === "string" && message.slice(0, 17) === "CLARA.IO DOWNLOAD") { ApplicationInterface.addAssetToWorldFromURL(message.slice(18)); } } diff --git a/interface/resources/qml/hifi/tablet/WindowRoot.qml b/interface/resources/qml/hifi/tablet/WindowRoot.qml index ef2df5e218..d888375db2 100644 --- a/interface/resources/qml/hifi/tablet/WindowRoot.qml +++ b/interface/resources/qml/hifi/tablet/WindowRoot.qml @@ -118,7 +118,7 @@ Windows.ScrollingWindow { id: eventBridgeConnection target: eventBridge onWebEventReceived: { - if (message.slice(0, 17) === "CLARA.IO DOWNLOAD") { + if (typeof message === "string" && message.slice(0, 17) === "CLARA.IO DOWNLOAD") { ApplicationInterface.addAssetToWorldFromURL(message.slice(18)); } } diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml index 66661843e6..cedbfb0fe1 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml @@ -9,6 +9,7 @@ // import QtQuick 2.5 +import QtQuick.Controls 2.2 import "." import "./preferences" @@ -33,7 +34,10 @@ Item { property bool gotoPreviousAppFromScript: false property var tablet; - + + readonly property real verticalScrollWidth: 10 + readonly property real verticalScrollShaft: 8 + function saveAll() { dialog.forceActiveFocus(); // Accept any text box edits in progress. @@ -103,6 +107,43 @@ Item { height: parent.height contentWidth: parent.width contentHeight: getSectionsHeight(); + + anchors.top: main.top + anchors.bottom: main.bottom + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + parent: scrollView.parent + anchors.top: scrollView.top + anchors.right: scrollView.right + anchors.bottom: scrollView.bottom + z: 100 // Display over top of separators. + + background: Item { + implicitWidth: verticalScrollWidth + Rectangle { + color: hifi.colors.baseGrayShadow + radius: 4 + anchors { + fill: parent + bottomMargin: 1 + } + } + } + contentItem: Item { + implicitWidth: verticalScrollShaft + Rectangle { + radius: verticalScrollShaft/2 + color: hifi.colors.white30 + anchors { + fill: parent + topMargin: 1 + bottomMargin: 1 + } + } + } + } + Column { width: 480 Component { @@ -183,7 +224,7 @@ Item { for (var i = 0; i < sections.length; i++) { totalHeight += sections[i].height + sections[i].getPreferencesHeight(); } - var bottomPadding = 170; + var bottomPadding = 30; return (totalHeight + bottomPadding); } } diff --git a/interface/resources/qml/windows/ScrollingWindow.qml b/interface/resources/qml/windows/ScrollingWindow.qml index 70640a2b75..0c91b58e31 100644 --- a/interface/resources/qml/windows/ScrollingWindow.qml +++ b/interface/resources/qml/windows/ScrollingWindow.qml @@ -97,11 +97,10 @@ Windows.Window { background: Item { implicitWidth: verticalScrollWidth Rectangle { - color: hifi.colors.darkGray30 + color: hifi.colors.baseGrayShadow radius: 4 anchors { fill: parent - topMargin: -1 // Finesse size bottomMargin: -2 } } @@ -113,7 +112,6 @@ Windows.Window { color: hifi.colors.white30 anchors { fill: parent - leftMargin: 2 // Finesse size and position. topMargin: 1 bottomMargin: 1 } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 776f78774c..1b22dbd329 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -111,6 +111,7 @@ #include #include #include +#include #include #include #include @@ -512,27 +513,6 @@ std::atomic DeadlockWatchdogThread::_maxElapsed; std::atomic DeadlockWatchdogThread::_maxElapsedAverage; ThreadSafeMovingAverage DeadlockWatchdogThread::_movingAverage; -bool isDomainURL(QUrl url) { - if (!url.isValid()) { - return false; - } - if (url.scheme() == URL_SCHEME_HIFI) { - return true; - } - if (url.scheme() != HIFI_URL_SCHEME_FILE) { - // TODO -- once Octree::readFromURL no-longer takes over the main event-loop, serverless-domain urls can - // be loaded over http(s) - // && url.scheme() != HIFI_URL_SCHEME_HTTP && - // url.scheme() != HIFI_URL_SCHEME_HTTPS - return false; - } - if (url.path().endsWith(".json", Qt::CaseInsensitive) || - url.path().endsWith(".json.gz", Qt::CaseInsensitive)) { - return true; - } - return false; -} - #ifdef Q_OS_WIN static const UINT UWM_IDENTIFY_INSTANCES = RegisterWindowMessage("UWM_IDENTIFY_INSTANCES_{8AB82783-B74A-4258-955B-8188C22AA0D6}_" + qgetenv("USERNAME")); @@ -564,14 +544,6 @@ public: return true; } - if (message->message == WM_COPYDATA) { - COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)(message->lParam); - QUrl url = QUrl((const char*)(pcds->lpData)); - if (isDomainURL(url)) { - DependencyManager::get()->handleLookupString(url.toString()); - return true; - } - } // Attempting to close MIDI interfaces of a hot-unplugged device can result in audio-driver deadlock. // Detecting MIDI devices that have been added/removed after starting Inteface has been disabled. // https://support.microsoft.com/en-us/help/4460006/midi-device-app-hangs-when-former-midi-api-is-used @@ -1167,7 +1139,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Graphik-SemiBold.ttf"); QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Graphik-Regular.ttf"); QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "fonts/Graphik-Medium.ttf"); - _window->setWindowTitle("High Fidelity"); + _window->setWindowTitle("Project Athena"); Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us @@ -1225,7 +1197,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // set the account manager's root URL and trigger a login request if we don't have the access token accountManager->setIsAgent(true); - accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL()); + accountManager->setAuthURL(MetaverseAPI::getCurrentMetaverseServerURL()); if (!accountManager->hasKeyPair()) { accountManager->generateNewUserKeypair(); } @@ -3194,7 +3166,7 @@ void Application::showLoginScreen() { QJsonObject loginData = {}; loginData["action"] = "login dialog popped up"; UserActivityLogger::getInstance().logAction("encourageLoginDialog", loginData); - _window->setWindowTitle("High Fidelity"); + _window->setWindowTitle("Project Athena"); } else { resumeAfterLoginDialogActionTaken(); } @@ -3212,10 +3184,30 @@ void Application::initializeUi() { // Allow remote QML content from trusted sources ONLY { auto defaultUrlValidator = OffscreenQmlSurface::getUrlValidator(); - auto newValidator = [=](const QUrl& url)->bool { - if (AUTHORIZED_EXTERNAL_QML_SOURCE.isParentOf(url)) { - return true; + auto newValidator = [=](const QUrl& url) -> bool { + QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; + QList safeURLS = { "" }; + safeURLS += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + + // PULL SAFEURLS FROM INTERFACE.JSON Settings + + QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); + QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); + safeURLS += settingsSafeURLS; + + // END PULL SAFEURLS FROM INTERFACE.JSON Settings + + bool isInWhitelist = false; // assume unsafe + for (const auto& str : safeURLS) { + if (!str.isEmpty() && str.endsWith(".qml") && url.toString().endsWith(".qml") && + url.toString().startsWith(str)) { + qCDebug(interfaceapp) << "Found matching url!" << url.host(); + isInWhitelist = true; + return true; + } } + + qCDebug(interfaceapp) << "No matching url" << url.host(); return defaultUrlValidator(url); }; OffscreenQmlSurface::setUrlValidator(newValidator); @@ -4053,7 +4045,7 @@ void Application::setIsServerlessMode(bool serverlessDomain) { } } -std::map Application::prepareServerlessDomainContents(QUrl domainURL) { +std::map Application::prepareServerlessDomainContents(QUrl domainURL, QByteArray data) { QUuid serverlessSessionID = QUuid::createUuid(); getMyAvatar()->setSessionUUID(serverlessSessionID); auto nodeList = DependencyManager::get(); @@ -4064,14 +4056,13 @@ std::map Application::prepareServerlessDomainContents(QUrl dom permissions.setAll(true); nodeList->setPermissions(permissions); - // we can't import directly into the main tree because we would need to lock it, and - // Octree::readFromURL calls loop.exec which can run code which will also attempt to lock the tree. + // FIXME: Lock the main tree and import directly into it. EntityTreePointer tmpTree(new EntityTree()); tmpTree->setIsServerlessMode(true); tmpTree->createRootElement(); auto myAvatar = getMyAvatar(); tmpTree->setMyAvatar(myAvatar); - bool success = tmpTree->readFromURL(domainURL.toString()); + bool success = tmpTree->readFromByteArray(domainURL.toString(), data); if (success) { tmpTree->reaverageOctreeElements(); tmpTree->sendEntities(&_entityEditSender, getEntities()->getTree(), 0, 0, 0); @@ -4094,12 +4085,26 @@ void Application::loadServerlessDomain(QUrl domainURL) { return; } - auto namedPaths = prepareServerlessDomainContents(domainURL); - auto nodeList = DependencyManager::get(); + QString trimmedUrl = domainURL.toString().trimmed(); + bool DEFAULT_IS_OBSERVABLE = true; + const qint64 DEFAULT_CALLER_ID = -1; + auto request = DependencyManager::get()->createResourceRequest( + this, trimmedUrl, DEFAULT_IS_OBSERVABLE, DEFAULT_CALLER_ID, "Application::loadServerlessDomain"); - nodeList->getDomainHandler().connectedToServerless(namedPaths); + if (!request) { + return; + } - _fullSceneReceivedCounter++; + connect(request, &ResourceRequest::finished, this, [=]() { + if (request->getResult() == ResourceRequest::Success) { + auto namedPaths = prepareServerlessDomainContents(domainURL, request->getData()); + auto nodeList = DependencyManager::get(); + nodeList->getDomainHandler().connectedToServerless(namedPaths); + _fullSceneReceivedCounter++; + } + request->deleteLater(); + }); + request->send(); } void Application::loadErrorDomain(QUrl domainURL) { @@ -4108,16 +4113,7 @@ void Application::loadErrorDomain(QUrl domainURL) { return; } - if (domainURL.isEmpty()) { - return; - } - - auto namedPaths = prepareServerlessDomainContents(domainURL); - auto nodeList = DependencyManager::get(); - - nodeList->getDomainHandler().loadedErrorDomain(namedPaths); - - _fullSceneReceivedCounter++; + loadServerlessDomain(domainURL); } bool Application::importImage(const QString& urlString) { @@ -5539,6 +5535,8 @@ bool Application::importEntities(const QString& urlOrFilename, const bool isObse _entityClipboard->withWriteLock([&] { _entityClipboard->eraseAllOctreeElements(); + // FIXME: readFromURL() can take over the main event loop which may cause problems, especially if downloading the JSON + // from the Web. success = _entityClipboard->readFromURL(urlOrFilename, isObservable, callerId); if (success) { _entityClipboard->reaverageOctreeElements(); @@ -7065,7 +7063,7 @@ void Application::updateWindowTitle() const { auto accountManager = DependencyManager::get(); auto isInErrorState = nodeList->getDomainHandler().isInErrorState(); - QString buildVersion = " - " + QString buildVersion = " - Project Athena v0.86.0 K2 - " + (BuildInfo::BUILD_TYPE == BuildInfo::BuildType::Stable ? QString("Version") : QString("Build")) + " " + applicationVersion(); @@ -7749,7 +7747,7 @@ bool Application::askToReplaceDomainContent(const QString& url) { static const QString infoText = simpleWordWrap("Your domain's content will be replaced with a new content set. " "If you want to save what you have now, create a backup before proceeding. For more information about backing up " "and restoring content, visit the documentation page at: ", MAX_CHARACTERS_PER_LINE) + - "\nhttps://docs.projectathena.dev/host/maintain-domain.html"; + "\nhttps://docs.projectathena.dev/host/maintain-domain/backup-domain.html"; ModalDialogListener* dig = OffscreenUi::asyncQuestion("Are you sure you want to replace this domain's content set?", infoText, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); @@ -8503,7 +8501,7 @@ void Application::loadAddAvatarBookmarkDialog() const { void Application::loadAvatarBrowser() const { auto tablet = dynamic_cast(DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")); // construct the url to the marketplace item - QString url = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace?category=avatars"; + QString url = MetaverseAPI::getCurrentMetaverseServerURL().toString() + "/marketplace?category=avatars"; QString MARKETPLACES_INJECT_SCRIPT_PATH = "file:///" + qApp->applicationDirPath() + "/scripts/system/html/js/marketplacesInject.js"; tablet->gotoWebScreen(url, MARKETPLACES_INJECT_SCRIPT_PATH); @@ -9258,7 +9256,7 @@ void Application::readArgumentsFromLocalSocket() const { // If we received a message, try to open it as a URL if (message.length() > 0) { - DependencyManager::get()->openUrl(QString::fromUtf8(message)); + DependencyManager::get()->handleLookupString(QString::fromUtf8(message)); } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 114bca864d..198f5ef7cf 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -464,7 +464,7 @@ public slots: void setPreferredCursor(const QString& cursor); void setIsServerlessMode(bool serverlessDomain); - std::map prepareServerlessDomainContents(QUrl domainURL); + std::map prepareServerlessDomainContents(QUrl domainURL, QByteArray data); void loadServerlessDomain(QUrl domainURL); void loadErrorDomain(QUrl domainURL); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 2aed828f53..b5cacd662b 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -288,6 +288,19 @@ Menu::Menu() { hmd->toggleShouldShowTablet(); } }); + + // Settings > Entity Script / QML Whitelist + action = addActionToQMenuAndActionHash(settingsMenu, "Entity Script / QML Whitelist"); + connect(action, &QAction::triggered, [] { + auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); + auto hmd = DependencyManager::get(); + + tablet->pushOntoStack("hifi/dialogs/security/EntityScriptQMLWhitelist.qml"); + + if (!hmd->getShouldShowTablet()) { + hmd->toggleShouldShowTablet(); + } + }); // Settings > Developer Menu addCheckableActionToQMenuAndActionHash(settingsMenu, "Developer Menu", 0, false, this, SLOT(toggleDeveloperMenus())); @@ -769,30 +782,30 @@ Menu::Menu() { // Help/Application menu ---------------------------------- MenuWrapper * helpMenu = addMenu("Help"); - // Help > About High Fidelity - action = addActionToQMenuAndActionHash(helpMenu, "About High Fidelity"); + // Help > About Project Athena + action = addActionToQMenuAndActionHash(helpMenu, "About Project Athena"); connect(action, &QAction::triggered, [] { qApp->showDialog(QString("hifi/dialogs/AboutDialog.qml"), QString("hifi/dialogs/TabletAboutDialog.qml"), "AboutDialog"); }); helpMenu->addSeparator(); - // Help > HiFi Docs + // Help > Athena Docs action = addActionToQMenuAndActionHash(helpMenu, "Online Documentation"); connect(action, &QAction::triggered, qApp, [] { - QDesktopServices::openUrl(QUrl("https://docs.highfidelity.com/")); + QDesktopServices::openUrl(QUrl("https://docs.projectathena.dev/")); }); - // Help > HiFi Forum - action = addActionToQMenuAndActionHash(helpMenu, "Online Forums"); + // Help > Athena Forum + /* action = addActionToQMenuAndActionHash(helpMenu, "Online Forums"); connect(action, &QAction::triggered, qApp, [] { QDesktopServices::openUrl(QUrl("https://forums.highfidelity.com/")); - }); + }); */ // Help > Scripting Reference action = addActionToQMenuAndActionHash(helpMenu, "Online Script Reference"); connect(action, &QAction::triggered, qApp, [] { - QDesktopServices::openUrl(QUrl("https://docs.highfidelity.com/api-reference")); + QDesktopServices::openUrl(QUrl("https://apidocs.projectathena.dev/")); }); addActionToQMenuAndActionHash(helpMenu, "Controls Reference", 0, qApp, SLOT(showHelp())); @@ -802,13 +815,13 @@ Menu::Menu() { // Help > Release Notes action = addActionToQMenuAndActionHash(helpMenu, "Release Notes"); connect(action, &QAction::triggered, qApp, [] { - QDesktopServices::openUrl(QUrl("https://docs.highfidelity.com/release-notes.html")); + QDesktopServices::openUrl(QUrl("https://docs.projectathena.dev/release-notes.html")); }); // Help > Report a Bug! action = addActionToQMenuAndActionHash(helpMenu, "Report a Bug!"); connect(action, &QAction::triggered, qApp, [] { - QDesktopServices::openUrl(QUrl("mailto:support@highfidelity.com")); + QDesktopServices::openUrl(QUrl("https://github.com/kasenvr/project-athena/issues")); }); } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index cd751e444a..3fcb261705 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -180,6 +180,7 @@ namespace MenuOption { const QString RunningScripts = "Running Scripts..."; const QString RunTimingTests = "Run Timing Tests"; const QString ScriptedMotorControl = "Enable Scripted Motor Control"; + const QString EntityScriptQMLWhitelist = "Entity Script / QML Whitelist"; const QString ShowTrackedObjects = "Show Tracked Objects"; const QString SelfieCamera = "Selfie"; const QString SendWrongDSConnectVersion = "Send wrong DS connect version"; diff --git a/interface/src/avatar/AvatarProject.h b/interface/src/avatar/AvatarProject.h index 0a63290051..4c1e55fa1c 100644 --- a/interface/src/avatar/AvatarProject.h +++ b/interface/src/avatar/AvatarProject.h @@ -95,7 +95,7 @@ public: static bool isValidNewProjectName(const QString& projectPath, const QString& projectName); static QString getDefaultProjectsPath() { - return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/High Fidelity Projects"; + return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/Project Athena Projects"; } signals: diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f723471b64..4736362fcb 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3905,7 +3905,7 @@ void MyAvatar::updateActionMotor(float deltaTime) { } _actionMotorVelocity = motorSpeed * direction; } else { - _actionMotorVelocity = direction; + _actionMotorVelocity = sensorToWorldScale * direction; } float previousBoomLength = _boomLength; diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 60fefa5878..4a41374ba3 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "Wallet.h" @@ -181,21 +182,28 @@ QString hfcString(const QJsonValue& sentValue, const QJsonValue& receivedValue) } return result; } -static const QString USER_PAGE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/users/"; -static const QString PLACE_PAGE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/places/"; + +QString getUserPageBaseUrl() { + return MetaverseAPI::getCurrentMetaverseServerURL().toString() + "/users/"; +} + +QString getPlacePageBaseUrl() { + return MetaverseAPI::getCurrentMetaverseServerURL().toString() + "/places/"; +} + static const QStringList KNOWN_USERS(QStringList() << "highfidelity" << "marketplace"); QString userLink(const QString& username, const QString& placename) { if (username.isEmpty()) { if (placename.isEmpty()) { return QString("someone"); } else { - return QString("someone nearby").arg(PLACE_PAGE_BASE_URL, placename); + return QString("someone nearby").arg(getPlacePageBaseUrl(), placename); } } if (KNOWN_USERS.contains(username)) { return username; } - return QString("%2").arg(USER_PAGE_BASE_URL, username); + return QString("%2").arg(getUserPageBaseUrl(), username); } QString transactionString(const QJsonObject& valueObject) { diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index c8ea044f4b..47105e0f3a 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -72,11 +72,11 @@ void QmlCommerce::openSystemApp(const QString& appName) { else if (appPathIter->contains(".html", Qt::CaseInsensitive)) { QMap::const_iterator injectIter = systemInject.find(appName); if (appPathIter == systemInject.end()) { - tablet->gotoWebScreen(NetworkingConstants::METAVERSE_SERVER_URL().toString() + *appPathIter); + tablet->gotoWebScreen(MetaverseAPI::getCurrentMetaverseServerURL().toString() + *appPathIter); } else { QString inject = "file:///" + qApp->applicationDirPath() + *injectIter; - tablet->gotoWebScreen(NetworkingConstants::METAVERSE_SERVER_URL().toString() + *appPathIter, inject); + tablet->gotoWebScreen(MetaverseAPI::getCurrentMetaverseServerURL().toString() + *appPathIter, inject); } } else { diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 5ca4d18a45..81616e5773 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -262,7 +262,9 @@ int main(int argc, const char* argv[]) { if (socket.waitForConnected(LOCAL_SERVER_TIMEOUT_MS)) { if (parser.isSet(urlOption)) { QUrl url = QUrl(parser.value(urlOption)); - if (url.isValid() && (url.scheme() == URL_SCHEME_HIFI || url.scheme() == URL_SCHEME_HIFIAPP)) { + if (url.isValid() && (url.scheme() == URL_SCHEME_HIFI || url.scheme() == URL_SCHEME_HIFIAPP + || url.scheme() == HIFI_URL_SCHEME_HTTP || url.scheme() == HIFI_URL_SCHEME_HTTPS + || url.scheme() == HIFI_URL_SCHEME_FILE)) { qDebug() << "Writing URL to local socket"; socket.write(url.toString().toUtf8()); if (!socket.waitForBytesWritten(5000)) { diff --git a/interface/src/networking/CloseEventSender.cpp b/interface/src/networking/CloseEventSender.cpp index 16549d5510..5397c221ad 100644 --- a/interface/src/networking/CloseEventSender.cpp +++ b/interface/src/networking/CloseEventSender.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -28,7 +29,7 @@ QNetworkRequest createNetworkRequest() { QNetworkRequest request; - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + QUrl requestURL = MetaverseAPI::getCurrentMetaverseServerURL(); requestURL.setPath(USER_ACTIVITY_URL); request.setUrl(requestURL); diff --git a/interface/src/raypick/StylusPick.h b/interface/src/raypick/StylusPick.h index 27514efefa..89444149d8 100644 --- a/interface/src/raypick/StylusPick.h +++ b/interface/src/raypick/StylusPick.h @@ -31,6 +31,8 @@ public: surfaceNormal = stylusPickResult.surfaceNormal; } + StylusPickResult& operator=(const StylusPickResult &right) = default; + IntersectionType type { NONE }; bool intersects { false }; QUuid objectID; diff --git a/interface/src/ui/AddressBarDialog.h b/interface/src/ui/AddressBarDialog.h index 1254fabbd2..aa3c11e810 100644 --- a/interface/src/ui/AddressBarDialog.h +++ b/interface/src/ui/AddressBarDialog.h @@ -15,6 +15,7 @@ #include #include +#include class AddressBarDialog : public OffscreenQmlDialog { Q_OBJECT @@ -30,7 +31,7 @@ public: bool forwardEnabled() { return _forwardEnabled; } bool useFeed() { return _useFeed; } void setUseFeed(bool useFeed) { if (_useFeed != useFeed) { _useFeed = useFeed; emit useFeedChanged(); } } - QString metaverseServerUrl() { return NetworkingConstants::METAVERSE_SERVER_URL().toString(); } + QString metaverseServerUrl() { return MetaverseAPI::getCurrentMetaverseServerURL().toString(); } signals: void backEnabledChanged(); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 1c8a9019ea..0f1c8978f0 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -305,7 +306,7 @@ void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID QNetworkRequest networkRequest; networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + QUrl requestURL = MetaverseAPI::getCurrentMetaverseServerURL(); requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); QJsonObject request; request["certificate_id"] = entityProperties.getCertificateID(); diff --git a/interface/src/workload/PhysicsBoundary.cpp b/interface/src/workload/PhysicsBoundary.cpp index cc78789145..02f7633a44 100644 --- a/interface/src/workload/PhysicsBoundary.cpp +++ b/interface/src/workload/PhysicsBoundary.cpp @@ -1,5 +1,5 @@ // -// PhysicsBoundary.h +// PhysicsBoundary.cpp // // Created by Andrew Meadows 2018.04.05 // Copyright 2018 High Fidelity, Inc. diff --git a/launchers/qt/CMakeLists.txt b/launchers/qt/CMakeLists.txt index 8155400f45..596f3b7d5c 100644 --- a/launchers/qt/CMakeLists.txt +++ b/launchers/qt/CMakeLists.txt @@ -45,7 +45,7 @@ if (WIN32) ExternalProject_Add( qtlite - URL "https://public.highfidelity.com/dependencies/qtlite/qt-lite-5.9.9-win-oct-15-2019.zip" + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/qtlite/qt-lite-5.9.9-win-oct-15-2019.zip" URL_HASH MD5=0176277bca37d219e83738caf3a698eb CONFIGURE_COMMAND "" BUILD_COMMAND "" @@ -78,7 +78,7 @@ endif () if (APPLE) ExternalProject_Add( qtlite - URL "https://public.highfidelity.com/dependencies/qtlite/qt-lite-5.9.9-mac.zip" + URL "${EXTERNAL_BUILD_ASSETS}/dependencies/qtlite/qt-lite-5.9.9-mac.zip" URL_HASH MD5=0cd78d40e5f539a7e314cf99b6cae0d0 CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index bcad7867cc..aa7e8fb69e 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -162,6 +162,7 @@ protected: const QString& typeVarIn, const QString& weightVarIn, float weightIn, const std::vector& flexCoefficientsIn, const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar); IKTargetVar(const IKTargetVar& orig); + AnimInverseKinematics::IKTargetVar& operator=(const AnimInverseKinematics::IKTargetVar&) = default; QString jointName; QString positionVar; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index d456961b69..d9ad82fb51 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2154,7 +2154,7 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi int deviceChannelCount = _outputFormat.channelCount(); int frameSize = (AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * deviceChannelCount * _outputFormat.sampleRate()) / _desiredOutputFormat.sampleRate(); int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE; - _audioOutput->setBufferSize(requestedSize); + _audioOutput->setBufferSize(requestedSize * 16); connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 5dbcd8e924..f38a6c23bc 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -169,7 +169,8 @@ render::hifi::Layer EntityRenderer::getHifiRenderLayer() const { } ItemKey EntityRenderer::getKey() { - ItemKey::Builder builder = ItemKey::Builder().withTypeShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + ItemKey::Builder builder = + ItemKey::Builder().withTypeShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); if (isTransparent()) { builder.withTransparent(); diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index d851e6d608..227eb6a018 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -110,6 +110,15 @@ protected: virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; } virtual void setCullWithParent(bool value) { _cullWithParent = value; } + template + T withReadLockResult(const std::function& f) { + T result; + withReadLock([&] { + result = f(); + }); + return result; + } + signals: void requestRenderUpdate(); diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index b1feddfd47..1da4999bad 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -28,6 +28,7 @@ #include "EntitiesRendererLogging.h" #include +#include using namespace render; using namespace render::entities; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 2e799d2535..5fc99882c0 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -3225,7 +3226,7 @@ void EntityItem::retrieveMarketplacePublicKey() { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest; networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + QUrl requestURL = MetaverseAPI::getCurrentMetaverseServerURL(); requestURL.setPath("/api/v1/commerce/marketplace_key"); QJsonObject request; networkRequest.setUrl(requestURL); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index ebdbbc4397..8c20914ec7 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1377,7 +1377,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * var METERS_TO_INCHES = 39.3701; * var entity = Entities.addEntity({ * type: "Web", - * sourceUrl: "https://highfidelity.com/", + * sourceUrl: "https://projectathena.io/", * position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -4 })), * rotation: MyAvatar.orientation, * dimensions: { diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 70fcb018fc..264fc3881b 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -122,6 +122,8 @@ public: QByteArray& blob, bool allProperties = false); EntityItemProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()); + EntityItemProperties(const EntityItemProperties&) = default; + virtual ~EntityItemProperties() = default; void merge(const EntityItemProperties& other); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index d1e83dccc2..e0f14b47e7 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -110,6 +110,10 @@ public: * displayed and so knows about. For assignment client scripts, the entities available are those that are "seen" by the * {@link EntityViewer}. For entity server scripts, all entities are available.

* + *

Entity Types

+ * + *

For a list of the entity types that you can use, see {@link Entities.EntityType|Entity Types}.

+ * *

Entity Methods

* *

Some of the API's signals correspond to entity methods that are called, if present, in the entity being interacted with. diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index e21339706a..11cd6309da 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "AccountManager.h" #include #include @@ -1485,7 +1486,7 @@ void EntityTree::startDynamicDomainVerificationOnServer(float minimumAgeToRemove QNetworkRequest networkRequest; networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + QUrl requestURL = MetaverseAPI::getCurrentMetaverseServerURL(); requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/location"); QJsonObject request; request["certificate_id"] = certificateID; @@ -1708,7 +1709,7 @@ void EntityTree::validatePop(const QString& certID, const EntityItemID& entityIt QNetworkRequest networkRequest; networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + QUrl requestURL = MetaverseAPI::getCurrentMetaverseServerURL(); requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); QJsonObject request; request["certificate_id"] = certID; diff --git a/libraries/entities/src/SimulationOwner.h b/libraries/entities/src/SimulationOwner.h index 6f37066e47..4039719cd3 100644 --- a/libraries/entities/src/SimulationOwner.h +++ b/libraries/entities/src/SimulationOwner.h @@ -112,6 +112,7 @@ public: SimulationOwner(); SimulationOwner(const QUuid& id, uint8_t priority); + SimulationOwner(const SimulationOwner &) = default; const QUuid& getID() const { return _id; } const uint64_t& getExpiry() const { return _expiry; } diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendState.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendState.cpp index 5da32f39df..0c2c0ae744 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendState.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendState.cpp @@ -204,10 +204,7 @@ void GLBackend::do_setStateDepthTest(State::DepthTest test) { glDepthFunc(COMPARISON_TO_GL[test.getFunction()]); } if (CHECK_GL_ERROR()) { - qCDebug(gpulogging) << "DepthTest" << (test.isEnabled() ? "Enabled" : "Disabled") - << "Mask=" << (test.getWriteMask() ? "Write" : "no Write") - << "Func=" << (uint16_t)test.getFunction() - << "Raw=" << test.getRaw(); + qCDebug(gpulogging) << "DepthTest = " << test; } _pipeline._stateCache.depthTest = test; } diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp index 89ba80031b..3236fa05e7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLState.cpp @@ -119,7 +119,7 @@ void generateDepthBias(GLState::Commands& commands, const State& state) { } void generateDepthTest(GLState::Commands& commands, const State::DepthTest& test) { - commands.push_back(std::make_shared(&GLBackend::do_setStateDepthTest, int32(test.getRaw()))); + commands.push_back(std::make_shared(&GLBackend::do_setStateDepthTest, test)); } void generateStencil(GLState::Commands& commands, const State& state) { diff --git a/libraries/gpu/src/gpu/Format.h b/libraries/gpu/src/gpu/Format.h index 25bb2baba4..61518edb6c 100644 --- a/libraries/gpu/src/gpu/Format.h +++ b/libraries/gpu/src/gpu/Format.h @@ -377,7 +377,7 @@ public: }; -enum ComparisonFunction : uint16 { +enum ComparisonFunction { NEVER = 0, LESS, EQUAL, diff --git a/libraries/gpu/src/gpu/FrameReader.cpp b/libraries/gpu/src/gpu/FrameReader.cpp index d636c6aaca..96f6b99f7a 100644 --- a/libraries/gpu/src/gpu/FrameReader.cpp +++ b/libraries/gpu/src/gpu/FrameReader.cpp @@ -734,7 +734,7 @@ BatchPointer Deserializer::readBatch(const json& node) { std::string batchName; if (node.count(keys::name)) { - batchName = node[keys::name]; + batchName = node.value(keys::name, ""); } BatchPointer result = std::make_shared(batchName); auto& batch = *result; diff --git a/libraries/gpu/src/gpu/State.cpp b/libraries/gpu/src/gpu/State.cpp index fab0438f75..81a43f87ae 100755 --- a/libraries/gpu/src/gpu/State.cpp +++ b/libraries/gpu/src/gpu/State.cpp @@ -94,20 +94,3 @@ static std::string hex(T t) { stream << std::hex << t; return stream.str(); } - -std::string State::getKey() const { - std::string key; - key = hex(*(int*)&_values.depthBias); - key += ":" + hex(*(int*)&_values.depthBiasSlopeScale); - key += ":" + hex(_values.depthTest.getRaw()); - key += ":" + hex(_values.stencilActivation.getRaw()); - key += ":" + hex(_values.stencilTestFront.getRaw()); - key += ":" + hex(_values.stencilTestBack.getRaw()); - key += ":" + hex(_values.blendFunction.getRaw()); - key += ":" + hex(_values.sampleMask); - // fillMode, cullMode, colorMaskWrite and the flags consume 32 bits alltogether - static_assert(0 == offsetof(State::Data, fillMode) % 4, "Validate fillMode offset"); - key += ":" + hex(*(int*)&_values.fillMode); - return key; -} - diff --git a/libraries/gpu/src/gpu/State.h b/libraries/gpu/src/gpu/State.h index 2e8a3f2cab..86bc5d4c5a 100755 --- a/libraries/gpu/src/gpu/State.h +++ b/libraries/gpu/src/gpu/State.h @@ -18,6 +18,7 @@ #include #include #include +#include // Why a macro and not a fancy template you will ask me ? // Because some of the fields are bool packed tightly in the State::Cache class @@ -46,7 +47,7 @@ public: typedef ::gpu::ComparisonFunction ComparisonFunction; - enum FillMode : uint8 + enum FillMode { FILL_POINT = 0, FILL_LINE, @@ -55,7 +56,7 @@ public: NUM_FILL_MODES, }; - enum CullMode : uint8 + enum CullMode { CULL_NONE = 0, CULL_FRONT, @@ -64,7 +65,7 @@ public: NUM_CULL_MODES, }; - enum StencilOp : uint16 + enum StencilOp { STENCIL_OP_KEEP = 0, STENCIL_OP_ZERO, @@ -78,7 +79,7 @@ public: NUM_STENCIL_OPS, }; - enum BlendArg : uint16 + enum BlendArg { ZERO = 0, ONE, @@ -99,7 +100,7 @@ public: NUM_BLEND_ARGS, }; - enum BlendOp : uint16 + enum BlendOp { BLEND_OP_ADD = 0, BLEND_OP_SUBTRACT, @@ -110,7 +111,7 @@ public: NUM_BLEND_OPS, }; - enum ColorMask : uint8 + enum ColorMask { WRITE_NONE = 0, WRITE_RED = 1, @@ -134,19 +135,27 @@ public: ComparisonFunction getFunction() const { return function; } uint8 getWriteMask() const { return writeMask; } - int32 getRaw() const { return *(reinterpret_cast(this)); } - DepthTest(int32 raw) { *(reinterpret_cast(this)) = raw; } - bool operator==(const DepthTest& right) const { return getRaw() == right.getRaw(); } - bool operator!=(const DepthTest& right) const { return getRaw() != right.getRaw(); } + bool operator==(const DepthTest& right) const { + return + writeMask == right.writeMask && + enabled == right.enabled && + function == right.function; + } + + bool operator!=(const DepthTest& right) const { + return !(*this == right); + } + + operator QString() const { + return QString("{ writeMask = %1, enabled = %2, function = %3 }").arg(writeMask).arg(enabled).arg(function); + } }; - static_assert(sizeof(DepthTest) == sizeof(uint32_t), "DepthTest size check"); - struct StencilTest { - ComparisonFunction function : 4; - StencilOp failOp : 4; - StencilOp depthFailOp : 4; - StencilOp passOp : 4; + ComparisonFunction function; + StencilOp failOp; + StencilOp depthFailOp; + StencilOp passOp; int8 reference{ 0 }; uint8 readMask{ 0xff }; @@ -168,47 +177,56 @@ public: int8 getReference() const { return reference; } uint8 getReadMask() const { return readMask; } - int32 getRaw() const { return *(reinterpret_cast(this)); } - StencilTest(int32 raw) { *(reinterpret_cast(this)) = raw; } - bool operator==(const StencilTest& right) const { return getRaw() == right.getRaw(); } - bool operator!=(const StencilTest& right) const { return getRaw() != right.getRaw(); } + bool operator==(const StencilTest& right) const { + return + function == right.function && + failOp == right.failOp && + depthFailOp == right.depthFailOp && + passOp == right.passOp && + reference == right.reference && + readMask == right.readMask; + + } + + bool operator!=(const StencilTest &right) const { return !(right==*this); } }; - static_assert(sizeof(StencilTest) == sizeof(uint32_t), "StencilTest size check"); StencilTest stencilTestFront; struct StencilActivation { uint8 frontWriteMask = 0xFF; uint8 backWriteMask = 0xFF; - bool enabled : 1; - uint8 _spare1 : 7; - uint8 _spare2{ 0 }; + bool enabled; public: StencilActivation(bool enabled = false, uint8 frontWriteMask = 0xFF, uint8 backWriteMask = 0xFF) : - frontWriteMask(frontWriteMask), backWriteMask(backWriteMask), enabled(enabled), _spare1{ 0 } {} + frontWriteMask(frontWriteMask), backWriteMask(backWriteMask), enabled(enabled) {} bool isEnabled() const { return enabled; } uint8 getWriteMaskFront() const { return frontWriteMask; } uint8 getWriteMaskBack() const { return backWriteMask; } - int32 getRaw() const { return *(reinterpret_cast(this)); } - StencilActivation(int32 raw) { *(reinterpret_cast(this)) = raw; } - bool operator==(const StencilActivation& right) const { return getRaw() == right.getRaw(); } - bool operator!=(const StencilActivation& right) const { return getRaw() != right.getRaw(); } - }; + bool operator==(const StencilActivation& right) const { + return + frontWriteMask == right.frontWriteMask && + backWriteMask == right.backWriteMask && + enabled == right.enabled; + } - static_assert(sizeof(StencilActivation) == sizeof(uint32_t), "StencilActivation size check"); + bool operator!=(const StencilActivation& right) const { + return !(*this == right); + } + }; struct BlendFunction { // Using uint8 here will make the structure as a whole not align to 32 bits - uint16 enabled : 8; - BlendArg sourceColor : 4; - BlendArg sourceAlpha : 4; - BlendArg destColor : 4; - BlendArg destAlpha : 4; - BlendOp opColor : 4; - BlendOp opAlpha : 4; + uint16 enabled; + BlendArg sourceColor; + BlendArg sourceAlpha; + BlendArg destColor; + BlendArg destAlpha; + BlendOp opColor; + BlendOp opAlpha; public: BlendFunction(bool enabled, @@ -219,7 +237,7 @@ public: BlendOp operationAlpha, BlendArg destinationAlpha) : enabled(enabled), - sourceColor(sourceColor), sourceAlpha(sourceAlpha), + sourceColor(sourceColor), sourceAlpha(sourceAlpha), destColor(destinationColor), destAlpha(destinationAlpha), opColor(operationColor), opAlpha(operationAlpha) {} @@ -236,32 +254,51 @@ public: BlendArg getDestinationAlpha() const { return destAlpha; } BlendOp getOperationAlpha() const { return opAlpha; } - int32 getRaw() const { return *(reinterpret_cast(this)); } - BlendFunction(int32 raw) { *(reinterpret_cast(this)) = raw; } - bool operator==(const BlendFunction& right) const { return getRaw() == right.getRaw(); } - bool operator!=(const BlendFunction& right) const { return getRaw() != right.getRaw(); } - }; + bool operator==(const BlendFunction& right) const { + return + enabled == right.enabled && + sourceColor == right.sourceColor && + sourceAlpha == right.sourceAlpha && + destColor == right.destColor && + destAlpha == right.destAlpha && + opColor == right.opColor && + opAlpha == right.opAlpha; - static_assert(sizeof(BlendFunction) == sizeof(uint32_t), "BlendFunction size check"); + } + + bool operator!=(const BlendFunction& right) const { + return !(*this == right); + } + }; struct Flags { Flags() : frontFaceClockwise(false), depthClampEnable(false), scissorEnable(false), multisampleEnable(true), - antialisedLineEnable(true), alphaToCoverageEnable(false), _spare1(0) {} - bool frontFaceClockwise : 1; - bool depthClampEnable : 1; - bool scissorEnable : 1; - bool multisampleEnable : 1; - bool antialisedLineEnable : 1; - bool alphaToCoverageEnable : 1; - uint8 _spare1 : 2; + antialisedLineEnable(true), alphaToCoverageEnable(false) {} + bool frontFaceClockwise; + bool depthClampEnable; + bool scissorEnable; + bool multisampleEnable; + bool antialisedLineEnable; + bool alphaToCoverageEnable; - bool operator==(const Flags& right) const { return *(uint8*)this == *(uint8*)&right; } - bool operator!=(const Flags& right) const { return *(uint8*)this != *(uint8*)&right; } + + bool operator==(const Flags& right) const { + return + frontFaceClockwise == right.frontFaceClockwise && + depthClampEnable == right.depthClampEnable && + scissorEnable == right.scissorEnable && + multisampleEnable == right.multisampleEnable && + antialisedLineEnable == right.antialisedLineEnable && + alphaToCoverageEnable == right.alphaToCoverageEnable; + + } + + bool operator!=(const Flags& right) const { + return !(*this == right); + } }; - static_assert(sizeof(Flags) == sizeof(uint8), "Flags size check"); - // The Data class is the full explicit description of the State class fields value. // Useful for having one const static called Default for reference or for the gpu::Backend to keep track of the current value class Data { @@ -282,22 +319,6 @@ public: Flags flags; }; - static_assert(offsetof(Data, depthBias) == 0, "Data offsets"); - static_assert(offsetof(Data, depthBiasSlopeScale) == 4, "Data offsets"); - static_assert(offsetof(Data, depthTest) == 8, "Data offsets"); - static_assert(offsetof(Data, stencilActivation) == 12, "Data offsets"); - static_assert(offsetof(Data, stencilTestFront) == 16, "Data offsets"); - static_assert(offsetof(Data, stencilTestBack) == 20, "Data offsets"); - static_assert(offsetof(Data, sampleMask) == 24, "Data offsets"); - static_assert(offsetof(Data, blendFunction) == 28, "Data offsets"); - static_assert(offsetof(Data, fillMode) == 32, "Data offsets"); - static_assert(offsetof(Data, cullMode) == 33, "Data offsets"); - static_assert(offsetof(Data, colorWriteMask) == 34, "Data offsets"); - static_assert(offsetof(Data, flags) == 35, "Data offsets"); - static_assert(sizeof(Data) == 36, "Data Size Check"); - - std::string getKey() const; - // The unique default values for all the fields static const Data DEFAULT; void setFillMode(FillMode fill) { SET_FIELD(FILL_MODE, fillMode, fill); } diff --git a/libraries/image/src/image/Image.h b/libraries/image/src/image/Image.h index dd39383dfb..14aa12d11a 100644 --- a/libraries/image/src/image/Image.h +++ b/libraries/image/src/image/Image.h @@ -59,7 +59,7 @@ namespace image { Image() : _dims(0,0) {} Image(int width, int height, Format format); Image(const QImage& data) : _packedData(data), _dims(data.width(), data.height()), _format((Format)data.format()) {} - + Image(const Image &other) = default; void operator=(const QImage& other) { _packedData = other; _floatData.clear(); diff --git a/libraries/material-networking/src/material-networking/TextureCache.cpp b/libraries/material-networking/src/material-networking/TextureCache.cpp index 8ffcad0c69..4831223fe9 100644 --- a/libraries/material-networking/src/material-networking/TextureCache.cpp +++ b/libraries/material-networking/src/material-networking/TextureCache.cpp @@ -43,9 +43,10 @@ #include #include -#include "NetworkLogging.h" +#include #include "MaterialNetworkingLogging.h" -#include "NetworkingConstants.h" +#include +#include #include #include diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index 7dc4d0dc13..26fbe502a0 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -24,8 +24,9 @@ #include "AccountSettings.h" #include "DataServerAccountInfo.h" #include "NetworkingConstants.h" +#include "MetaverseAPI.h" #include "NetworkAccessManager.h" -#include "SharedUtil.h" +#include class JSONCallbackParameters { public: @@ -99,7 +100,7 @@ public: void setTemporaryDomain(const QUuid& domainID, const QString& key); const QString& getTemporaryDomainKey(const QUuid& domainID) { return _accountInfo.getTemporaryDomainKey(domainID); } - QUrl getMetaverseServerURL() { return NetworkingConstants::METAVERSE_SERVER_URL(); } + QUrl getMetaverseServerURL() { return MetaverseAPI::getCurrentMetaverseServerURL(); } void removeAccountFromFile(); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 7d1318fedd..5f08f19d2b 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -157,6 +157,7 @@ void AddressManager::storeCurrentAddress() { auto url = currentAddress(); if (url.scheme() == HIFI_URL_SCHEME_FILE || + url.scheme() == HIFI_URL_SCHEME_HTTP || url.scheme() == HIFI_URL_SCHEME_HTTPS || (url.scheme() == URL_SCHEME_HIFI && !url.host().isEmpty())) { // TODO -- once Octree::readFromURL no-longer takes over the main event-loop, serverless-domain urls can // be loaded over http(s) @@ -266,8 +267,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) { if (lookupUrl.scheme() == URL_SCHEME_HIFI) { if (lookupUrl.host().isEmpty()) { // this was in the form hifi:/somewhere or hifi:somewhere. Fix it by making it hifi://somewhere - static const QRegExp HIFI_SCHEME_REGEX = QRegExp(URL_SCHEME_HIFI + ":\\/?($|\\w+)", Qt::CaseInsensitive); - lookupUrl = QUrl(lookupUrl.toString().replace(HIFI_SCHEME_REGEX, URL_SCHEME_HIFI + "://\\1")); + static const QRegExp HIFI_SCHEME_REGEX = QRegExp(URL_SCHEME_HIFI + ":\\/{0,2}", Qt::CaseInsensitive); + lookupUrl = QUrl(lookupUrl.toString().replace(HIFI_SCHEME_REGEX, URL_SCHEME_HIFI + "://")); } DependencyManager::get()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::LookupAddress); @@ -361,13 +362,11 @@ bool AddressManager::handleUrl(const QUrl& lookupUrlIn, LookupTrigger trigger) { emit lookupResultsFinished(); return true; - } else if (lookupUrl.scheme() == HIFI_URL_SCHEME_FILE) { - // TODO -- once Octree::readFromURL no-longer takes over the main event-loop, serverless-domain urls can - // be loaded over http(s) - // lookupUrl.scheme() == URL_SCHEME_HTTP || - // lookupUrl.scheme() == HIFI_URL_SCHEME_HTTPS || - // TODO once a file can return a connection refusal if there were to be some kind of load error, we'd - // need to store the previous domain tried in _lastVisitedURL. For now , do not store it. + } else if (lookupUrl.scheme() == HIFI_URL_SCHEME_FILE || lookupUrl.scheme() == HIFI_URL_SCHEME_HTTPS + || lookupUrl.scheme() == HIFI_URL_SCHEME_HTTP) { + + // Save the last visited domain URL. + _lastVisitedURL = lookupUrl; _previousAPILookup.clear(); _shareablePlaceName.clear(); diff --git a/libraries/networking/src/AssetUtils.cpp b/libraries/networking/src/AssetUtils.cpp index 6fb914a8b2..b0eb19bb73 100644 --- a/libraries/networking/src/AssetUtils.cpp +++ b/libraries/networking/src/AssetUtils.cpp @@ -21,6 +21,7 @@ #include "NetworkAccessManager.h" #include "NetworkLogging.h" #include "NetworkingConstants.h" +#include "MetaverseAPI.h" #include "ResourceManager.h" diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 3512b02d11..fa4e3dc29b 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -209,7 +209,9 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { } // if it's in the error state, reset and try again. - if ((_domainURL != domainURL || _sockAddr.getPort() != domainPort) || _isInErrorState) { + if (_domainURL != domainURL + || (_sockAddr.getPort() != domainPort && domainURL.scheme() == URL_SCHEME_HIFI) + || _isInErrorState) { // re-set the domain info so that auth information is reloaded hardReset("Changing domain URL"); diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 505bbb94b5..68059fb158 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -31,6 +31,7 @@ #include "Node.h" #include "ReceivedMessage.h" #include "NetworkingConstants.h" +#include "MetaverseAPI.h" const unsigned short DEFAULT_DOMAIN_SERVER_PORT = QProcessEnvironment::systemEnvironment() diff --git a/libraries/networking/src/FileResourceRequest.cpp b/libraries/networking/src/FileResourceRequest.cpp index 11489f13bd..f9ec7797be 100644 --- a/libraries/networking/src/FileResourceRequest.cpp +++ b/libraries/networking/src/FileResourceRequest.cpp @@ -22,6 +22,7 @@ #include "NetworkLogging.h" #include "ResourceManager.h" #include "NetworkingConstants.h" +#include "MetaverseAPI.h" void FileResourceRequest::doSend() { auto statTracker = DependencyManager::get(); diff --git a/libraries/networking/src/MetaverseAPI.cpp b/libraries/networking/src/MetaverseAPI.cpp new file mode 100644 index 0000000000..0fb0bcecad --- /dev/null +++ b/libraries/networking/src/MetaverseAPI.cpp @@ -0,0 +1,38 @@ +// +// MetaverseAPI.cpp +// libraries/networking/src +// +// Created by Kalila (kasenvr) on 2019-12-16. +// Copyright 2019 Project Athena +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "MetaverseAPI.h" + +#include +#include +#include "NetworkingConstants.h" +#include + + +namespace MetaverseAPI { + // You can change the return of this function if you want to use a custom metaverse URL at compile time + // or you can pass a custom URL via the env variable + QUrl getCurrentMetaverseServerURL() { + QUrl selectedMetaverseURL; + Setting::Handle selectedMetaverseURLSetting("private/selectedMetaverseURL", + NetworkingConstants::METAVERSE_SERVER_URL_STABLE); + + selectedMetaverseURL = selectedMetaverseURLSetting.get(); + + const QString HIFI_METAVERSE_URL_ENV = "HIFI_METAVERSE_URL"; + + if (QProcessEnvironment::systemEnvironment().contains(HIFI_METAVERSE_URL_ENV)) { + return QUrl(QProcessEnvironment::systemEnvironment().value(HIFI_METAVERSE_URL_ENV)); + } + + return selectedMetaverseURL; + }; +} diff --git a/libraries/networking/src/MetaverseAPI.h b/libraries/networking/src/MetaverseAPI.h new file mode 100644 index 0000000000..423f465229 --- /dev/null +++ b/libraries/networking/src/MetaverseAPI.h @@ -0,0 +1,22 @@ +// +// MetaverseAPI.h +// libraries/networking/src +// +// Created by Kalila (kasenvr) on 2019-12-16. +// Copyright 2019 Project Athena +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef athena_MetaverseAPI_h +#define athena_MetaverseAPI_h + +#include +#include + +namespace MetaverseAPI { + QUrl getCurrentMetaverseServerURL(); +} + +#endif // athena_MetaverseAPI_h diff --git a/libraries/networking/src/NetworkingConstants.cpp b/libraries/networking/src/NetworkingConstants.cpp deleted file mode 100644 index 622c307efa..0000000000 --- a/libraries/networking/src/NetworkingConstants.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// NetworkingConstants.cpp -// libraries/networking/src -// -// Created by Seth Alves on 2018-2-28. -// Copyright 2018 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include "NetworkingConstants.h" - -namespace NetworkingConstants { - // You can change the return of this function if you want to use a custom metaverse URL at compile time - // or you can pass a custom URL via the env variable - QUrl METAVERSE_SERVER_URL() { - const QString HIFI_METAVERSE_URL_ENV = "HIFI_METAVERSE_URL"; - const QUrl serverURL = QProcessEnvironment::systemEnvironment().contains(HIFI_METAVERSE_URL_ENV) - ? QUrl(QProcessEnvironment::systemEnvironment().value(HIFI_METAVERSE_URL_ENV)) - : METAVERSE_SERVER_URL_STABLE; - return serverURL; - }; -} diff --git a/libraries/networking/src/NetworkingConstants.h b/libraries/networking/src/NetworkingConstants.h index 117a41c976..fabf8b0e44 100644 --- a/libraries/networking/src/NetworkingConstants.h +++ b/libraries/networking/src/NetworkingConstants.h @@ -26,8 +26,7 @@ namespace NetworkingConstants { // at https://staging.highfidelity.com/user/tokens/new?for_domain_server=true const QUrl METAVERSE_SERVER_URL_STABLE { "https://metaverse.highfidelity.com" }; - const QUrl METAVERSE_SERVER_URL_STAGING { "https://staging.highfidelity.com" }; - QUrl METAVERSE_SERVER_URL(); + const QUrl METAVERSE_SERVER_URL_STAGING { "https://staging.projectathena.io" }; } const QString HIFI_URL_SCHEME_ABOUT = "about"; diff --git a/libraries/networking/src/OAuthNetworkAccessManager.cpp b/libraries/networking/src/OAuthNetworkAccessManager.cpp index 272ff47a49..b1e04da4b6 100644 --- a/libraries/networking/src/OAuthNetworkAccessManager.cpp +++ b/libraries/networking/src/OAuthNetworkAccessManager.cpp @@ -18,6 +18,7 @@ #include "AccountManager.h" #include "LimitedNodeList.h" #include "NetworkingConstants.h" +#include "MetaverseAPI.h" #include "SharedUtil.h" QThreadStorage oauthNetworkAccessManagers; @@ -35,7 +36,7 @@ QNetworkReply* OAuthNetworkAccessManager::createRequest(QNetworkAccessManager::O auto accountManager = DependencyManager::get(); if (accountManager->hasValidAccessToken() - && req.url().host() == NetworkingConstants::METAVERSE_SERVER_URL().host()) { + && req.url().host() == MetaverseAPI::getCurrentMetaverseServerURL().host()) { QNetworkRequest authenticatedRequest(req); authenticatedRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); authenticatedRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 948acd3d78..269ff94b80 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -35,6 +35,9 @@ void UserActivityLogger::disable(bool disable) { } void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCallbackParameters params) { +// qCDebug(networking).nospace() << ">>> UserActivityLogger::logAction(" << action << "," << QJsonDocument(details).toJson(); +// This logs what the UserActivityLogger would normally send to centralized servers. + return; if (_disabled.get()) { return; } diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index df02b54856..aac0de27a1 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -738,7 +738,6 @@ bool Octree::readFromURL( ) { QString trimmedUrl = urlString.trimmed(); QString marketplaceID = getMarketplaceID(trimmedUrl); - qDebug() << "!!!!! going to createResourceRequest " << callerId; auto request = std::unique_ptr( DependencyManager::get()->createResourceRequest( this, trimmedUrl, isObservable, callerId, "Octree::readFromURL")); @@ -770,6 +769,24 @@ bool Octree::readFromURL( return readFromStream(data.size(), inputStream, marketplaceID); } +bool Octree::readFromByteArray( + const QString& urlString, + const QByteArray& data +) { + QString trimmedUrl = urlString.trimmed(); + QString marketplaceID = getMarketplaceID(trimmedUrl); + + QByteArray uncompressedJsonData; + bool wasCompressed = gunzip(data, uncompressedJsonData); + + if (wasCompressed) { + QDataStream inputStream(uncompressedJsonData); + return readFromStream(uncompressedJsonData.size(), inputStream, marketplaceID); + } + + QDataStream inputStream(data); + return readFromStream(data.size(), inputStream, marketplaceID); +} bool Octree::readFromStream( uint64_t streamLength, diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 4f994da60e..45dae3049d 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -217,6 +217,7 @@ public: // Octree importers bool readFromFile(const char* filename); bool readFromURL(const QString& url, const bool isObservable = true, const qint64 callerId = -1); // will support file urls as well... + bool readFromByteArray(const QString& url, const QByteArray& byteArray); bool readFromStream(uint64_t streamLength, QDataStream& inputStream, const QString& marketplaceID=""); bool readSVOFromStream(uint64_t streamLength, QDataStream& inputStream); bool readJSONFromStream(uint64_t streamLength, QDataStream& inputStream, const QString& marketplaceID=""); diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index 22bfc3f1ad..88c111f8fd 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "ShaderConstants.h" diff --git a/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp b/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp index 0b64429d15..130f11f3ef 100644 --- a/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp +++ b/libraries/procedural/src/procedural/ProceduralMaterialCache.cpp @@ -163,6 +163,13 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater *

  • "CULL_BACK" (the default) to cull the back faces of the geometry.
  • * * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. + * @property {string} cullFaceMode - The mode defining which side of the geometry should be rendered. Values can be: + *
      + *
    • "CULL_NONE" for rendering both sides of the geometry.
    • + *
    • "CULL_FRONT" for culling the front faces of the geometry.
    • + *
    • "CULL_BACK" (the default) for culling the back faces of the geometry.
    • + *
    + * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. * @property {string} roughnessMap - The URL of the roughness texture image. You can use this or glossMap, but not * both. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index d9fc8117bd..2678cb5591 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include "Logging.h" #include "impl/SharedObject.h" diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index f62dca8a26..0786ef62ca 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -23,8 +23,8 @@ #include "RenderPipelines.h" -static const QString ENABLE_MATERIAL_PROCEDURAL_SHADERS_STRING { "HIFI_ENABLE_MATERIAL_PROCEDURAL_SHADERS" }; -static bool ENABLE_MATERIAL_PROCEDURAL_SHADERS = QProcessEnvironment::systemEnvironment().contains(ENABLE_MATERIAL_PROCEDURAL_SHADERS_STRING); +// static const QString ENABLE_MATERIAL_PROCEDURAL_SHADERS_STRING { "HIFI_ENABLE_MATERIAL_PROCEDURAL_SHADERS" }; +// static bool ENABLE_MATERIAL_PROCEDURAL_SHADERS = QProcessEnvironment::systemEnvironment().contains(ENABLE_MATERIAL_PROCEDURAL_SHADERS_STRING); bool MeshPartPayload::enableMaterialProceduralShaders = false; @@ -193,7 +193,7 @@ void MeshPartPayload::render(RenderArgs* args) { if (!_drawMaterials.empty() && _drawMaterials.top().material && _drawMaterials.top().material->isProcedural() && _drawMaterials.top().material->isReady()) { - if (!(enableMaterialProceduralShaders && ENABLE_MATERIAL_PROCEDURAL_SHADERS)) { + if (!enableMaterialProceduralShaders) { return; } auto procedural = std::static_pointer_cast(_drawMaterials.top().material); @@ -480,7 +480,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) { if (!_drawMaterials.empty() && _drawMaterials.top().material && _drawMaterials.top().material->isProcedural() && _drawMaterials.top().material->isReady()) { - if (!(enableMaterialProceduralShaders && ENABLE_MATERIAL_PROCEDURAL_SHADERS)) { + if (!(enableMaterialProceduralShaders)) { return; } auto procedural = std::static_pointer_cast(_drawMaterials.top().material); diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp index 068d6f9851..8cedbc7f3e 100644 --- a/libraries/render/src/render/CullTask.cpp +++ b/libraries/render/src/render/CullTask.cpp @@ -130,6 +130,10 @@ void FetchSpatialTree::configure(const Config& config) { } void FetchSpatialTree::run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemSpatialTree::ItemSelection& outSelection) { + if (!renderContext){ + return; + } + // start fresh outSelection.clear(); @@ -142,6 +146,10 @@ void FetchSpatialTree::run(const RenderContextPointer& renderContext, const Inpu RenderArgs* args = renderContext->args; auto& scene = renderContext->_scene; + if (!args) { + return; + } + auto queryFrustum = args->getViewFrustum(); // Eventually use a frozen frustum if (_freezeFrustum) { diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 9141b5e1c7..3b2a122e71 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -84,6 +84,11 @@ #include "../../midi/src/Midi.h" // FIXME why won't a simpler include work? #include "MIDIEvent.h" +#include "SettingHandle.h" +#include +#include + + const QString ScriptEngine::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS { "com.highfidelity.experimental.enableExtendedJSExceptions" }; @@ -258,7 +263,7 @@ QString ScriptEngine::getContext() const { return "unknown"; } -bool ScriptEngine::isDebugMode() const { +bool ScriptEngine::isDebugMode() const { #if defined(DEBUG) return true; #else @@ -815,6 +820,11 @@ void ScriptEngine::init() { #if DEV_BUILD || PR_BUILD registerGlobalObject("StackTest", new StackTestScriptingInterface(this)); #endif + + globalObject().setProperty("KALILA", "isWaifu"); + globalObject().setProperty("Kute", newFunction([](QScriptContext* context, QScriptEngine* engine) -> QScriptValue { + return context->argument(0).toString().toLower() == "kalila" ? true : false; + })); } void ScriptEngine::registerValue(const QString& valueName, QScriptValue value) { @@ -2366,6 +2376,7 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co BaseScriptEngine sandbox; sandbox.setProcessEventsInterval(SANDBOX_TIMEOUT); QScriptValue testConstructor, exception; + if (atoi(getenv("UNSAFE_ENTITY_SCRIPTS") ? getenv("UNSAFE_ENTITY_SCRIPTS") : "0")) { QTimer timeout; timeout.setSingleShot(true); @@ -2387,14 +2398,94 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co } else if (testConstructor.isError()) { exception = testConstructor; } + } else { + // ENTITY SCRIPT WHITELIST STARTS HERE + auto nodeList = DependencyManager::get(); + bool passList = false; // assume unsafe + QString whitelistPrefix = "[WHITELIST ENTITY SCRIPTS]"; + QList safeURLPrefixes = { "file:///", "atp:", "cache:" }; + safeURLPrefixes += qEnvironmentVariable("EXTRA_WHITELIST").trimmed().split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + + // Entity Script Whitelist toggle check. + Setting::Handle whitelistEnabled {"private/whitelistEnabled", false }; + + if (!whitelistEnabled.get()) { + passList = true; + } + + // Pull SAFEURLS from the Interface.JSON settings. + QVariant raw = Setting::Handle("private/settingsSafeURLS").get(); + QStringList settingsSafeURLS = raw.toString().trimmed().split(QRegExp("\\s*[,\r\n]+\\s*"), QString::SkipEmptyParts); + safeURLPrefixes += settingsSafeURLS; + // END Pull SAFEURLS from the Interface.JSON settings. + + // Get current domain whitelist bypass, in case an entire domain is whitelisted. + QString currentDomain = DependencyManager::get()->getDomainURL().host(); + + QString domainSafeIP = nodeList->getDomainHandler().getHostname(); + QString domainSafeURL = URL_SCHEME_HIFI + "://" + currentDomain; + for (const auto& str : safeURLPrefixes) { + if (domainSafeURL.startsWith(str) || domainSafeIP.startsWith(str)) { + qCDebug(scriptengine) << whitelistPrefix << "Whitelist Bypassed, entire domain is whitelisted. Current Domain Host: " + << nodeList->getDomainHandler().getHostname() + << "Current Domain: " << currentDomain; + passList = true; + } + } + // END bypass whitelist based on current domain. + + // Start processing scripts through the whitelist. + if (ScriptEngine::getContext() == "entity_server") { // If running on the server, do not engage whitelist. + passList = true; + } else if (!passList) { // If waved through, do not engage whitelist. + for (const auto& str : safeURLPrefixes) { + qCDebug(scriptengine) << whitelistPrefix << "Script URL: " << scriptOrURL << "TESTING AGAINST" << str << "RESULTS IN" + << scriptOrURL.startsWith(str); + if (!str.isEmpty() && scriptOrURL.startsWith(str)) { + passList = true; + qCDebug(scriptengine) << whitelistPrefix << "Script approved."; + break; // Bail early since we found a match. + } + } + } + // END processing of scripts through the whitelist. + + if (!passList) { // If the entity failed to pass for any reason, it's blocked and an error is thrown. + qCDebug(scriptengine) << whitelistPrefix << "(disabled entity script)" << entityID.toString() << scriptOrURL; + exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); + } else { + QTimer timeout; + timeout.setSingleShot(true); + timeout.start(SANDBOX_TIMEOUT); + connect(&timeout, &QTimer::timeout, [=, &sandbox] { + qCDebug(scriptengine) << "ScriptEngine::entityScriptContentAvailable timeout"; + + // Guard against infinite loops and non-performant code + sandbox.raiseException( + sandbox.makeError(QString("Timed out (entity constructors are limited to %1ms)").arg(SANDBOX_TIMEOUT))); + }); + + testConstructor = sandbox.evaluate(program); + + if (sandbox.hasUncaughtException()) { + exception = sandbox.cloneUncaughtException(QString("(preflight %1)").arg(entityID.toString())); + sandbox.clearExceptions(); + } else if (testConstructor.isError()) { + exception = testConstructor; + } + } + // ENTITY SCRIPT WHITELIST ENDS HERE, uncomment below for original full disabling. + + // qDebug() << "(disabled entity script)" << entityID.toString() << scriptOrURL; + // exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0"); } if (exception.isError()) { - // create a local copy using makeError to decouple from the sandbox engine - exception = makeError(exception); - setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); - emit unhandledException(exception); - return; + // create a local copy using makeError to decouple from the sandbox engine + exception = makeError(exception); + setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT); + emit unhandledException(exception); + return; } // CONSTRUCTOR VIABILITY @@ -2765,4 +2856,3 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS } } } - diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index fd2ebe300d..12eaa011a9 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -412,7 +412,7 @@ void ScriptEngines::stopAllScripts(bool restart) { continue; } - bool isOverrideScript = it.key().toString().compare(this->_defaultScriptsOverride.toString()); + bool isOverrideScript = it.key().toString().compare(this->_defaultScriptsOverride.toString()) == 0; // queue user scripts if restarting if (restart && (scriptEngine->isUserLoaded() || isOverrideScript)) { _isReloading = true; diff --git a/libraries/script-engine/src/WebSocketClass.cpp b/libraries/script-engine/src/WebSocketClass.cpp index 7333e38037..00d379aff4 100644 --- a/libraries/script-engine/src/WebSocketClass.cpp +++ b/libraries/script-engine/src/WebSocketClass.cpp @@ -16,6 +16,8 @@ #include "ScriptEngine.h" +#include "ScriptEngineLogging.h" + WebSocketClass::WebSocketClass(QScriptEngine* engine, QString url) : _webSocket(new QWebSocket()), _engine(engine) @@ -34,10 +36,11 @@ WebSocketClass::WebSocketClass(QScriptEngine* engine, QWebSocket* qWebSocket) : void WebSocketClass::initialize() { connect(_webSocket, &QWebSocket::disconnected, this, &WebSocketClass::handleOnClose); connect(_webSocket, &QWebSocket::textMessageReceived, this, &WebSocketClass::handleOnMessage); + connect(_webSocket, &QWebSocket::binaryMessageReceived, this, &WebSocketClass::handleOnBinaryMessage); connect(_webSocket, &QWebSocket::connected, this, &WebSocketClass::handleOnOpen); connect(_webSocket, static_cast(&QWebSocket::error), this, &WebSocketClass::handleOnError); - _binaryType = QStringLiteral("blob"); + _binaryType = QStringLiteral("arraybuffer"); } QScriptValue WebSocketClass::constructor(QScriptContext* context, QScriptEngine* engine) { @@ -53,7 +56,12 @@ WebSocketClass::~WebSocketClass() { } void WebSocketClass::send(QScriptValue message) { - _webSocket->sendTextMessage(message.toString()); + if (message.isObject()) { + QByteArray ba = qscriptvalue_cast(message); + _webSocket->sendBinaryMessage(ba); + } else { + _webSocket->sendTextMessage(message.toString()); + } } void WebSocketClass::close() { @@ -170,6 +178,25 @@ void WebSocketClass::handleOnMessage(const QString& message) { } } +void WebSocketClass::handleOnBinaryMessage(const QByteArray& message) { + if (_onMessageEvent.isFunction()) { + QScriptValueList args; + QScriptValue arg = _engine->newObject(); + QScriptValue data = _engine->newVariant(QVariant::fromValue(message)); + QScriptValue ctor = _engine->globalObject().property("ArrayBuffer"); + auto array = qscriptvalue_cast(ctor.data()); + QScriptValue arrayBuffer; + if (!array) { + qCWarning(scriptengine) << "WebSocketClass::handleOnBinaryMessage !ArrayBuffer"; + } else { + arrayBuffer = _engine->newObject(array, data); + } + arg.setProperty("data", arrayBuffer); + args << arg; + _onMessageEvent.call(QScriptValue(), args); + } +} + /**jsdoc * Called when the connection opens. * @callback WebSocket~onOpenCallback diff --git a/libraries/script-engine/src/WebSocketClass.h b/libraries/script-engine/src/WebSocketClass.h index 543f6146a6..3430068eee 100644 --- a/libraries/script-engine/src/WebSocketClass.h +++ b/libraries/script-engine/src/WebSocketClass.h @@ -236,6 +236,7 @@ private slots: void handleOnClose(); void handleOnError(QAbstractSocket::SocketError error); void handleOnMessage(const QString& message); + void handleOnBinaryMessage(const QByteArray& message); void handleOnOpen(); }; diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index 57514a2231..b0ceca5758 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -20,12 +20,11 @@ #include #include #include +#include #include "ResourceRequestObserver.h" #include "ScriptEngine.h" -const QString METAVERSE_API_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/api/"; - Q_DECLARE_METATYPE(QByteArray*) XMLHttpRequestClass::XMLHttpRequestClass(QScriptEngine* engine) : @@ -130,6 +129,8 @@ void XMLHttpRequestClass::open(const QString& method, const QString& url, bool a _url.setUrl(url); _async = async; + const QString METAVERSE_API_URL = MetaverseAPI::getCurrentMetaverseServerURL().toString() + "/api/"; + if (url.toLower().left(METAVERSE_API_URL.length()) == METAVERSE_API_URL) { auto accountManager = DependencyManager::get(); diff --git a/libraries/shared/src/CubicHermiteSpline.h b/libraries/shared/src/CubicHermiteSpline.h index c83000996b..f91b25aa7a 100644 --- a/libraries/shared/src/CubicHermiteSpline.h +++ b/libraries/shared/src/CubicHermiteSpline.h @@ -19,6 +19,8 @@ public: CubicHermiteSplineFunctor(const CubicHermiteSplineFunctor& orig) : _p0(orig._p0), _m0(orig._m0), _p1(orig._p1), _m1(orig._m1) {} + CubicHermiteSplineFunctor& operator=(const CubicHermiteSplineFunctor&) = default; + virtual ~CubicHermiteSplineFunctor() {} // evalute the hermite curve at parameter t (0..1) @@ -85,6 +87,8 @@ public: memcpy(_values, orig._values, sizeof(float) * (NUM_SUBDIVISIONS + 1)); } + CubicHermiteSplineFunctorWithArcLength& operator=(const CubicHermiteSplineFunctorWithArcLength&) = default; + // given the spline parameter (0..1) output the arcLength of the spline up to that point. float arcLength(float t) const { float index = t * NUM_SUBDIVISIONS; diff --git a/libraries/shared/src/shared/MediaTypeLibrary.h b/libraries/shared/src/shared/MediaTypeLibrary.h index c87da01fa1..d4931c1601 100644 --- a/libraries/shared/src/shared/MediaTypeLibrary.h +++ b/libraries/shared/src/shared/MediaTypeLibrary.h @@ -48,6 +48,7 @@ public: webMediaTypes(mediaType.webMediaTypes), fileSignatures(mediaType.fileSignatures) { } + MediaType& operator=(const MediaType&) = default; static MediaType NONE; diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 12cb7e2e4b..867302d955 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -269,7 +269,11 @@ void VrMenu::insertAction(QAction* before, QAction* action) { Q_ASSERT(invokeResult); QObject* result = reinterpret_cast(returnedValue); // returnedValue.value(); Q_ASSERT(result); - bindActionToQmlAction(result, action, _rootMenu); + if ( result ) { + bindActionToQmlAction(result, action, _rootMenu); + } else { + qWarning() << "Failed to find addItem() method in object " << menu << ". Not inserting action " << action; + } } class QQuickMenuBase; diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h index 90b734b42d..f8e4189d12 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.h +++ b/libraries/ui/src/ui/TabletScriptingInterface.h @@ -105,7 +105,7 @@ public: * @returns {TabletProxy} The tablet instance. * @example Display the High Fidelity home page on the system tablet. * var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - * tablet.gotoWebScreen("https://highfidelity.com/"); + * tablet.gotoWebScreen("https://projectathena.io/"); */ Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId); diff --git a/libraries/ui/src/ui/types/RequestFilters.cpp b/libraries/ui/src/ui/types/RequestFilters.cpp index 3fa1cd0bd9..943dd02c29 100644 --- a/libraries/ui/src/ui/types/RequestFilters.cpp +++ b/libraries/ui/src/ui/types/RequestFilters.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include "ContextAwareProfile.h" @@ -25,7 +26,7 @@ namespace { bool isAuthableHighFidelityURL(const QUrl& url) { - auto metaverseServerURL = NetworkingConstants::METAVERSE_SERVER_URL(); + auto metaverseServerURL = MetaverseAPI::getCurrentMetaverseServerURL(); static const QStringList HF_HOSTS = { "highfidelity.com", "highfidelity.io", metaverseServerURL.toString(), "metaverse.highfidelity.io" diff --git a/pkg-scripts/Dockerfile.templ b/pkg-scripts/Dockerfile.templ new file mode 100644 index 0000000000..76d27e8c78 --- /dev/null +++ b/pkg-scripts/Dockerfile.templ @@ -0,0 +1,43 @@ +FROM ubuntu:18.04 +ARG DEPENDS +ARG GITSRC +ARG GITDATE +ARG GITCOMMIT + +# starting out as root, will drop back in entrypoint.sh +USER root + +# expose ports for domain server +EXPOSE 40100 40101 40102 +EXPOSE 40100/udp 40101/udp 40102/udp + +# expose ports for assignment client +EXPOSE 48000/udp 48001/udp 48002/udp 48003/udp 48004/udp 48005/udp 48006/udp + +RUN echo UTC >/etc/timezone +RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ + apt-get install -y tzdata supervisor ${DEPENDS} && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + mkdir -p /var/lib/athena +RUN groupadd -r athena ; \ + useradd -Nr athena -d /var/lib/athena ; \ + usermod -aG athena athena ; \ + chown athena.athena /var/lib/athena ; \ + exit 0 + +VOLUME /var/lib/athena + +RUN mkdir -p /var/run ; chmod 777 /var/run +COPY athena.conf /etc/supervisor/conf.d/athena.conf + +COPY entrypoint.sh / +COPY opt /opt/athena +COPY lib /opt/athena/lib + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/athena.conf"] +LABEL \ + net.projectathena.gitsrc="${GITSRC}" \ + net.projectathena.gitdate="${GITDATE}" \ + net.projectathena.gitcommit="${GITCOMMIT}" diff --git a/pkg-scripts/README b/pkg-scripts/README new file mode 100644 index 0000000000..f4ef24eed4 --- /dev/null +++ b/pkg-scripts/README @@ -0,0 +1,60 @@ +Collection of scripts to create server distribution packages. Most of these scripts assume +use of the build script at https://github.com/daleglass/athena-builder, specifically that +the following directory structure exists + +base folder/ + source/ git checkout + build/ result of cmake build + qt5-install/ installed or built Qt5 installation + +These scripts assume that the current directory is the pkg-scripts folder inside of the source directory +and that the base folder can be reached by going to "../..". This may not work if pkg-scripts is a symlink; +adding an ATHENA=~/Athena to the beginning of the commandline will override where it looks for the base folder + +Ubuntu: + DEBEMAIL="your-email@somewhere.com" DEBFULLNAME="Your Full Name" ./make-deb-server + + This script will retrieve the current git commit date and hash and assemble a version from it. + It will attempt construct a .deb file in the pkg-scripts folder + +Amazon Linux 2: + ./make-rpm-server + + This script will retrieve the current git commit date and hash and assemble a version from it. + It will attempt construct an .rpm file in the pkg-scripts folder + +Docker: + ./make-docker-server + + This script will attempt to create a docker container + +Results: + The following directory structure is created for binaries: + /opt/athena - executables + /opt/athena/lib - private shared libraries required for executables + /opt/athena/resources - files required by domain-server administrative website + /opt/athena/plugins - files required by assignment-client, mainly for audio codecs + + The following systemd services are installed in /usr/lib/systemd/system: + athena-assignment-client.service + athena-domain-server.service + athena-server.target - used to launch/shutdown the two prior services + athena-assignment-client@.service + athena-domain-server@.service + athena-server@.target - used to launch/shutdown the two prior services + + The top three services in this list are the "normal" services that launch Athena + in the typical fashion. The bottom three services are "template" services designed + to permit multiple services to be installed and running on a single machine. + + The script "/opt/athena/new-server serverName basePort" will do the necessary + setup for a new domain with the specified server name and port. Upon installation + the package will create and launch a domain named "default" at base port 40100. + The domain name here has nothing to do with the name people will use to find your + domain and has nothing to do with "place names", it is only used to locate the files + used to configure and run the domain on your server. + + The server stores its files in the following locations: + /var/lib/athena/.local - "unnamed" services (the default location for Athena servers) + /var/lib/athena/serverName - "named" (template) domains + /etc/opt/athena - environment variables when launching named domains diff --git a/pkg-scripts/athena-assignment-client.service b/pkg-scripts/athena-assignment-client.service new file mode 100644 index 0000000000..a6407294dc --- /dev/null +++ b/pkg-scripts/athena-assignment-client.service @@ -0,0 +1,18 @@ +[Unit] +Description=Assignment client service for Athena server +After=network.target +PartOf=athena-server.target + +[Service] +Restart=always + +WorkingDirectory=/opt/athena +Environment="LD_LIBRARY_PATH=/opt/athena/lib" +User=athena +Group=athena +#LimitCORE=infinity +#ExecStart=/opt/athena/assignment-client -n 6 +ExecStart=/opt/athena/assignment-client --min 6 --max 20 + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/athena-assignment-client@.service b/pkg-scripts/athena-assignment-client@.service new file mode 100644 index 0000000000..7f60ed4d28 --- /dev/null +++ b/pkg-scripts/athena-assignment-client@.service @@ -0,0 +1,20 @@ +[Unit] +Description=Assignment client service for Athena server +After=network.target +PartOf=athena-server@%i.target + +[Service] +Restart=always + +WorkingDirectory=/opt/athena +EnvironmentFile=/etc/opt/athena/%i.conf +Environment="LD_LIBRARY_PATH=/opt/athena/lib" "HOME=/var/lib/athena/%i" +PrivateTmp=true +User=athena +Group=athena +#LimitCORE=infinity +#ExecStart=/opt/athena/assignment-client -n 6 +ExecStart=/opt/athena/assignment-client --min 6 --max 20 --server-port $HIFI_DOMAIN_SERVER_PORT + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/athena-domain-server.service b/pkg-scripts/athena-domain-server.service new file mode 100644 index 0000000000..a5db9dc269 --- /dev/null +++ b/pkg-scripts/athena-domain-server.service @@ -0,0 +1,18 @@ +[Unit] +Description=Domain Server service for Athena +After=network.target +PartOf=athena-server.target + +[Service] +Restart=on-failure + +WorkingDirectory=/opt/athena +Environment="LD_LIBRARY_PATH=/opt/athena/lib" +User=athena +Group=athena +#LimitCORE=infinity +#ExecStartPre=/bin/bash -c 'if /usr/bin/pgrep -l domain-server; then /usr/bin/pkill -SIGKILL -f /usr/share/hifi/domain-server/domain-server; fi' +ExecStart=/opt/athena/domain-server + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/athena-domain-server@.service b/pkg-scripts/athena-domain-server@.service new file mode 100644 index 0000000000..330d8ac81d --- /dev/null +++ b/pkg-scripts/athena-domain-server@.service @@ -0,0 +1,20 @@ +[Unit] +Description=Domain Server service for Athena +After=network.target +PartOf=athena-server@%i.target + +[Service] +Restart=on-failure + +WorkingDirectory=/opt/athena +EnvironmentFile=/etc/opt/athena/%i.conf +Environment="LD_LIBRARY_PATH=/opt/athena/lib" "HOME=/var/lib/athena/%i" +PrivateTmp=true +User=athena +Group=athena +#LimitCORE=infinity +#ExecStartPre=/bin/bash -c 'if /usr/bin/pgrep -l domain-server; then /usr/bin/pkill -SIGKILL -f /usr/share/hifi/domain-server/domain-server; fi' +ExecStart=/opt/athena/domain-server + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/athena-ice-server.service b/pkg-scripts/athena-ice-server.service new file mode 100644 index 0000000000..57db8581b3 --- /dev/null +++ b/pkg-scripts/athena-ice-server.service @@ -0,0 +1,18 @@ +[Unit] +Description=Ice Server service for Athena +After=network.target +PartOf=athena-server.target + +[Service] +Restart=on-failure + +Environment="HIFI_ENVIRONMENT=production" "LD_LIBRARY_PATH=/opt/athena/lib" +WorkingDirectory=/opt/athena +User=athena +Group=athena +#ExecStartPre=/bin/bash -c 'if /usr/bin/pgrep -l ice-server; then /usr/bin/pkill -SIGKILL -f /usr/share/hifi/ice-server/ice-server; fi' +#LimitCORE=infinity +ExecStart=/opt/athena/ice-server + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/athena-ice-server@.service b/pkg-scripts/athena-ice-server@.service new file mode 100644 index 0000000000..e4993f5436 --- /dev/null +++ b/pkg-scripts/athena-ice-server@.service @@ -0,0 +1,20 @@ +[Unit] +Description=Ice Server service for Athena +After=network.target +PartOf=athena-server@%i.target + +[Service] +Restart=on-failure + +EnvironmentFile=/etc/opt/athena/%i.conf +Environment="HIFI_ENVIRONMENT=production" "LD_LIBRARY_PATH=/opt/athena/lib" "HOME=/var/lib/athena/%i" +PrivateTmp=true +WorkingDirectory=/opt/athena +User=athena +Group=athena +#ExecStartPre=/bin/bash -c 'if /usr/bin/pgrep -l ice-server; then /usr/bin/pkill -SIGKILL -f /usr/share/hifi/ice-server/ice-server; fi' +#LimitCORE=infinity +ExecStart=/opt/athena/ice-server + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/athena-server.spec b/pkg-scripts/athena-server.spec new file mode 100644 index 0000000000..7910c8114b --- /dev/null +++ b/pkg-scripts/athena-server.spec @@ -0,0 +1,128 @@ +#ATHENA=~/Athena rpmbuild --target x86_64 -bb athena-server.spec +%define version %{lua:print(os.getenv("VERSION"))} +%define depends %{lua:print(os.getenv("DEPENDS"))} + +Name: athena-server +Version: %{version} +Release: 1%{?dist} +Summary: Project Athena metaverse platform, based on the High Fidelity Engine. + +License: ASL 2.0 +URL: https://projectathena.io +Source0: https://github.com/daleglass/athena-builder/blob/master/athena_builder + +#BuildRequires: systemd-rpm-macros +BuildRequires: chrpath +Requires: %{depends} +BuildArch: x86_64 +AutoReq: no +AutoProv: no + +%description +Project Athena allows creation and sharing of VR experiences. + The Project Athena metaverse provides built-in social features, including avatar interactions, spatialized audio and interactive physics. Additionally, you have the ability to import any 3D object into your virtual environment. + + +%prep + + +%build + + +%install +rm -rf $RPM_BUILD_ROOT +install -d $RPM_BUILD_ROOT/opt/athena +install -m 0755 -t $RPM_BUILD_ROOT/opt/athena $ATHENA/build/assignment-client/assignment-client +install -m 0755 -t $RPM_BUILD_ROOT/opt/athena $ATHENA/build/domain-server/domain-server +install -m 0755 -t $RPM_BUILD_ROOT/opt/athena $ATHENA/build/tools/oven/oven +#install -m 0755 -t $RPM_BUILD_ROOT/opt/athena $ATHENA/build/ice-server/ice-server +strip --strip-all $RPM_BUILD_ROOT/opt/athena/* +chrpath -d $RPM_BUILD_ROOT/opt/athena/* +install -m 0755 -t $RPM_BUILD_ROOT/opt/athena $ATHENA/source/pkg-scripts/new-server +install -d $RPM_BUILD_ROOT/opt/athena/lib +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/build/libraries/*/*.so +strip --strip-all $RPM_BUILD_ROOT/opt/athena/lib/* +chrpath -d $RPM_BUILD_ROOT/opt/athena/lib/* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5Network.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5Core.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5Widgets.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5Gui.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5Script.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5Quick.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5WebSockets.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5Qml.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/qt5-install/lib/libQt5ScriptTools.so.*.*.* +install -m 0644 -t $RPM_BUILD_ROOT/opt/athena/lib $ATHENA/build/ext/makefiles/quazip/project/lib/libquazip5.so.*.*.* +install -d $RPM_BUILD_ROOT/usr/lib/systemd/system +install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-assignment-client.service +install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-assignment-client@.service +install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-domain-server.service +install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-domain-server@.service +#install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-ice-server.service +#install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-ice-server@.service +install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-server.target +install -m 0644 -t $RPM_BUILD_ROOT/usr/lib/systemd/system $ATHENA/source/pkg-scripts/athena-server@.target +cp -a $ATHENA/source/domain-server/resources $RPM_BUILD_ROOT/opt/athena +cp -a $ATHENA/build/assignment-client/plugins $RPM_BUILD_ROOT/opt/athena +chrpath -d $RPM_BUILD_ROOT/opt/athena/plugins/*.so +chrpath -d $RPM_BUILD_ROOT/opt/athena/plugins/*/*.so +strip --strip-all $RPM_BUILD_ROOT/opt/athena/plugins/*.so +strip --strip-all $RPM_BUILD_ROOT/opt/athena/plugins/*/*.so +find $RPM_BUILD_ROOT/opt/athena/resources -name ".gitignore" -delete + + +%files +%license $ATHENA/source/LICENSE +/opt/athena +/usr/lib/systemd/system + + +%changelog + + +%post +# create users +getent passwd athena >/dev/numm 2>&1 || useradd -r -c "Project Athena" -d /var/lib/athena -U -M athena +#getent group athena >/dev/null 2>&1 || groupadd -r athena + +# create data folder +mkdir -p /etc/opt/athena +mkdir -p /var/lib/athena && chown athena:athena /var/lib/athena && chmod 775 /var/lib/athena + +ldconfig -n /opt/athena/lib +if [ ! -d "/var/lib/athena/default" ]; then + /opt/athena/new-server default 40100 + systemctl enable athena-server@default.target + systemctl start athena-server@default.target +fi + +%systemd_post athena-assignment-client.service +%systemd_post athena-assignment-client@.service +%systemd_post athena-domain-server.service +%systemd_post athena-domain-server@.service +#%systemd_post athena-ice-server.service +#%systemd_post athena-ice-server@.service +%systemd_post athena-server.target +%systemd_post athena-server@.target + + +%preun +%systemd_preun athena-server.target +%systemd_preun athena-server@.target +%systemd_preun athena-assignment-client.service +%systemd_preun athena-assignment-client@.service +%systemd_preun athena-domain-server.service +%systemd_preun athena-domain-server@.service +#%systemd_preun athena-ice-server.service +#%systemd_preun athena-ice-server@.service + + +%postun +%systemd_postun_with_restart athena-server.target +%systemd_postun_with_restart athena-server@.target +%systemd_postun_with_restart athena-assignment-client.service +%systemd_postun_with_restart athena-assignment-client@.service +%systemd_postun_with_restart athena-domain-server.service +%systemd_postun_with_restart athena-domain-server@.service +#%systemd_postun_with_restart athena-ice-server.service +#%systemd_postun_with_restart athena-ice-server@.service diff --git a/pkg-scripts/athena-server.target b/pkg-scripts/athena-server.target new file mode 100644 index 0000000000..e3929b401b --- /dev/null +++ b/pkg-scripts/athena-server.target @@ -0,0 +1,11 @@ +[Unit] +Description=Athena virtual domain +Wants=athena-assignment-client.service +Wants=athena-domain-server.service +#Wants=athena-ice-server.service +After=athena-assignment-client.service +After=athena-domain-server.service +#After=athena-ice-server.service + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/athena-server@.target b/pkg-scripts/athena-server@.target new file mode 100644 index 0000000000..8ac451ca80 --- /dev/null +++ b/pkg-scripts/athena-server@.target @@ -0,0 +1,11 @@ +[Unit] +Description=Athena virtual domain +Wants=athena-assignment-client@%i.service +Wants=athena-domain-server@%i.service +#Wants=athena-ice-server@%i.service +After=athena-assignment-client@%i.service +After=athena-domain-server@%i.service +#After=athena-ice-server@%i.service + +[Install] +WantedBy=multi-user.target diff --git a/pkg-scripts/docker-athena-supervisor.conf b/pkg-scripts/docker-athena-supervisor.conf new file mode 100644 index 0000000000..d6e53996b6 --- /dev/null +++ b/pkg-scripts/docker-athena-supervisor.conf @@ -0,0 +1,76 @@ +[supervisord] +user=athena +nodaemon=true +environment=HOME="/var/lib/athena",USER="athena",LD_LIBRARY_PATH="/opt/athena/lib" +logfile=/dev/stdout +logfile_maxbytes=0 +pidfile=/var/run/supervisord.pid + +[program:domain-server] +command=/opt/athena/domain-server +autorestart=unexpected +directory=/opt/athena + +[program:audio-mixer] +command=/opt/athena/assignment-client -t 0 -a localhost -p 48000 +autorestart=unexpected +directory=/opt/athena +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:avatar-mixer] +command=/opt/athena/assignment-client -t 1 -a localhost -p 48001 +autorestart=unexpected +directory=/opt/athena +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:entities-server] +command=/opt/athena/assignment-client -t 6 -a localhost -p 48006 +autorestart=unexpected +directory=/opt/athena +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:asset-server] +command=/opt/athena/assignment-client -t 3 -a localhost -p 48003 +autorestart=unexpected +directory=/opt/athena +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:entity-script-server] +command=/opt/athena/assignment-client -t 5 -a localhost -p 48005 +autorestart=unexpected +directory=/opt/athena +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:messages-mixer] +command=/opt/athena/assignment-client -t 4 -a localhost -p 48004 +autorestart=unexpected +directory=/opt/athena +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:scripted-agent] +command=/opt/athena/assignment-client -t 2 -a localhost --max 100 +autorestart=unexpected +directory=/opt/athena +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + diff --git a/pkg-scripts/docker-entrypoint.sh b/pkg-scripts/docker-entrypoint.sh new file mode 100755 index 0000000000..4a4a7506dc --- /dev/null +++ b/pkg-scripts/docker-entrypoint.sh @@ -0,0 +1,33 @@ +#!/bin/sh +set -x + + +# In Prod, this may be configured with a GID already matching the container +# allowing the container to be run directly as Jenkins. In Dev, or on unknown +# environments, run the container as root to automatically correct docker +# group in container to match the docker.sock GID mounted from the host. +if [ -f /var/lib/athena/.local -a "$(id -u)" = "0" ]; then + # realign gid + THIS_ATHENA_GID=`ls -ngd /var/lib/athena/.local | cut -f3 -d' '` + CUR_ATHENA_GID=`getent group athena | cut -f3 -d: || true` + if [ ! -z "$THIS_ATHENA_GID" -a "$THIS_ATHENA_GID" != "$CUR_ATHENA_GID" ]; then + groupmod -g ${THIS_ATHENA_GID} -o athena + fi + + # realign pid + THIS_ATHENA_PID=`ls -nd /var/lib/athena/.local | cut -f3 -d' '` + CUR_ATHENA_PID=`getent passwd athena | cut -f3 -d: || true` + if [ ! -z "$THIS_ATHENA_PID" -a "$THIS_ATHENA_PID" != "$CUR_ATHENA_PID" ]; then + usermod -u ${THIS_ATHENA_PID} -o athena + fi + + if ! groups athena | grep -q athena; then + usermod -aG athena athena + fi +fi + +chmod 777 /dev/stdout +chmod 777 /dev/stderr + +# continue with CMD +exec "$@" diff --git a/pkg-scripts/make-deb-server b/pkg-scripts/make-deb-server new file mode 100755 index 0000000000..72304ae414 --- /dev/null +++ b/pkg-scripts/make-deb-server @@ -0,0 +1,110 @@ +#!/bin/sh + +if [ "$ATHENA" = "" ]; then + ATHENA=`realpath ../..` +fi + +GITDATE=`git -C $ATHENA/source log -n 1 --format=raw | grep author | cut -d">" -f 2 | cut -d" " -f 2 | xargs -I {} date -d @{} +"%Y%m%d"` +GITCOMMIT=`git -C $ATHENA/source rev-parse HEAD | cut -c 1-7` +VERSION=0.86.0-k2-$GITDATE-$GITCOMMIT + +sudo apt-get install chrpath binutils dh-make + +DEB_BUILD_ROOT=temp-make-deb/athena-server-$VERSION-0ubuntu1 +rm -r temp-make-deb +mkdir -p $DEB_BUILD_ROOT + +# copy the files over +cp $ATHENA/build/assignment-client/assignment-client $DEB_BUILD_ROOT +cp $ATHENA/build/domain-server/domain-server $DEB_BUILD_ROOT +cp $ATHENA/build/tools/oven/oven $DEB_BUILD_ROOT +cp $ATHENA/build/libraries/*/*.so $DEB_BUILD_ROOT +#cp $ATHENA/build/ice-server/ice-server $DEB_BUILD_ROOT +chrpath -d $DEB_BUILD_ROOT/* +cp $ATHENA/qt5-install/lib/libQt5Network.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5Core.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5Widgets.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5Gui.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5Script.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5Quick.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5WebSockets.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5Qml.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/qt5-install/lib/libQt5ScriptTools.so.*.*.* $DEB_BUILD_ROOT +cp $ATHENA/build/ext/makefiles/quazip/project/lib/libquazip5.so.*.*.* $DEB_BUILD_ROOT +chmod +x $DEB_BUILD_ROOT/*.so.*.*.* +strip --strip-all $DEB_BUILD_ROOT/* +cp $ATHENA/source/pkg-scripts/new-server $DEB_BUILD_ROOT +cp -a $ATHENA/source/domain-server/resources $DEB_BUILD_ROOT +find $DEB_BUILD_ROOT/resources -name ".gitignore" -delete +find $DEB_BUILD_ROOT/resources -type f -executable -exec sh -c 'chmod -x {}' \; +cp $ATHENA/source/README.md $DEB_BUILD_ROOT +cp $ATHENA/source/README_hifi.md $DEB_BUILD_ROOT +cp -a $ATHENA/build/assignment-client/plugins $DEB_BUILD_ROOT +strip --strip-all $DEB_BUILD_ROOT/plugins/*.so +strip --strip-all $DEB_BUILD_ROOT/plugins/*/*.so + +#begin the debian package construction +cd $DEB_BUILD_ROOT +dh_make -p athena-server_$VERSION-0ubuntu1 -c apache -s --createorig -y + +cp $ATHENA/source/pkg-scripts/athena-assignment-client.service debian +cp $ATHENA/source/pkg-scripts/athena-assignment-client@.service debian +cp $ATHENA/source/pkg-scripts/athena-domain-server.service debian +cp $ATHENA/source/pkg-scripts/athena-domain-server@.service debian +#cp $ATHENA/source/pkg-scripts/athena-ice-server.service debian +#cp $ATHENA/source/pkg-scripts/athena-ice-server@.service debian +cp $ATHENA/source/pkg-scripts/athena-server.target debian +cp $ATHENA/source/pkg-scripts/athena-server@.target debian + +cp $ATHENA/source/pkg-scripts/server-control debian/control +cp $ATHENA/source/pkg-scripts/server-prerm debian/prerm +cp $ATHENA/source/pkg-scripts/server-postinst debian/postinst +cp $ATHENA/source/LICENSE debian/copyright + +echo /etc/opt/athena > debian/dirs +echo /var/lib/athena >> debian/dirs + +echo README.md > debian/docs +echo README_hifi.md >> debian/docs + +echo assignment-client opt/athena > debian/install +echo domain-server opt/athena >> debian/install +echo oven opt/athena >> debian/install +#echo ice-server opt/athena >> debian/install +echo new-server opt/athena >> debian/install +for so in *.so.*.*.*; do + echo $so opt/athena/lib >> debian/install +done +for so in *.so; do + echo $so opt/athena/lib >> debian/install +done +#for service in *.service; do +# echo $service opt/athena/systemd >> debian/install +#done +#for target in *.target; do +# echo $target opt/athena/systemd >> debian/install +#done +find resources -type f -exec sh -c 'echo {} opt/athena/$(dirname "{}") >> debian/install' \; +find plugins -type f -exec sh -c 'echo {} opt/athena/$(dirname "{}") >> debian/install' \; + +#echo usr/lib/systemd/system/athena-assignment-client.service opt/athena/systemd/athena-assignment-client.service > debian/athena-server.links +#echo usr/lib/systemd/system/athena-assignment-client@.service opt/athena/systemd/athena-assignment-client@.service >> debian/athena-server.links +#echo usr/lib/systemd/system/athena-domain-server.service opt/athena/systemd/athena-domain-server.service >> debian/athena-server.links +#echo usr/lib/systemd/system/athena-domain-server@.service opt/athena/systemd/athena-domain-server@.service >> debian/athena-server.links +##echo usr/lib/systemd/system/athena-ice-server.service opt/athena/systemd/athena-ice-server.service >> debian/athena-server.links +##echo usr/lib/systemd/system/athena-ice-server@.service opt/athena/systemd/athena-ice-server@.service >> debian/athena-server.links +#echo usr/lib/systemd/system/athena-server.target opt/athena/systemd/athena-server.target >> debian/athena-server.links +#echo usr/lib/systemd/system/athena-server@.target opt/athena/systemd/athena-server@.target >> debian/athena-server.links + +SOFILES=`ls *.so *.so.*.*.* | sed 's/\./\\\./g' | paste -d'|' -s` + +DEPENDS=`find * -type f -executable -exec sh -c 'objdump -p {} | grep NEEDED' \; | awk '{print $2}' | sort | uniq | egrep -v "^($SOFILES)$" | xargs -n 1 -I {} sh -c 'dpkg -S {} | head -n 1' | cut -d ':' -f 1 | sort | uniq | paste -d',' -s` + +cp $ATHENA/source/pkg-scripts/server-rules debian/rules +sed "s/{DEPENDS}/$DEPENDS/" $ATHENA/source/pkg-scripts/server-control > debian/control + +dpkg-buildpackage -us -uc + +cd .. +mv *.deb .. +cd .. diff --git a/pkg-scripts/make-docker-server b/pkg-scripts/make-docker-server new file mode 100755 index 0000000000..3ad37bb0e2 --- /dev/null +++ b/pkg-scripts/make-docker-server @@ -0,0 +1,60 @@ +#!/bin/sh + +if [ "$ATHENA" = "" ]; then + ATHENA=`realpath ../..` +fi + +GITSRC=`git -C $ATHENA/source config --get remote.origin.url | cut -d':' -f 2` +GITDATE=`git -C $ATHENA/source log -n 1 --format=raw | grep author | cut -d">" -f 2 | cut -d" " -f 2 | xargs -I {} date -d @{} +"%Y%m%d"` +GITCOMMIT=`git -C $ATHENA/source rev-parse HEAD | cut -c 1-7` + +sudo apt-get install chrpath binutils + +DOCK_BUILD_ROOT=temp-make-dock +rm -r temp-make-dock +mkdir -p $DOCK_BUILD_ROOT +cp $ATHENA/source/pkg-scripts/Dockerfile.templ $DOCK_BUILD_ROOT/Dockerfile +cp $ATHENA/source/pkg-scripts/docker-entrypoint.sh $DOCK_BUILD_ROOT/entrypoint.sh +cp $ATHENA/source/pkg-scripts/docker-athena-supervisor.conf $DOCK_BUILD_ROOT/athena.conf + +# copy the files over +mkdir -p $DOCK_BUILD_ROOT/opt +cp $ATHENA/build/assignment-client/assignment-client $DOCK_BUILD_ROOT/opt +cp $ATHENA/build/domain-server/domain-server $DOCK_BUILD_ROOT/opt +cp $ATHENA/build/tools/oven/oven $DOCK_BUILD_ROOT/opt +#cp $ATHENA/build/ice-server/ice-server $DOCK_BUILD_ROOT/opt +strip --strip-all $DOCK_BUILD_ROOT/opt/* +chrpath -d $DOCK_BUILD_ROOT/opt/* + +cp -a $ATHENA/build/assignment-client/plugins $DOCK_BUILD_ROOT/opt +strip --strip-all $DOCK_BUILD_ROOT/opt/plugins/*.so +chrpath -d $DOCK_BUILD_ROOT/opt/plugins/*.so +strip --strip-all $DOCK_BUILD_ROOT/opt/plugins/*/*.so +chrpath -d $DOCK_BUILD_ROOT/opt/plugins/*/*.so + +cp -a $ATHENA/source/domain-server/resources $DOCK_BUILD_ROOT/opt +find $DOCK_BUILD_ROOT/opt/resources -name ".gitignore" -delete +find $DOCK_BUILD_ROOT/opt/resources -type f -executable -exec sh -c 'chmod -x {}' \; + +mkdir -p $DOCK_BUILD_ROOT/lib +cp $ATHENA/build/libraries/*/*.so $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5Network.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5Core.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5Widgets.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5Gui.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5Script.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5Quick.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5WebSockets.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5Qml.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/qt5-install/lib/libQt5ScriptTools.so.*.*.* $DOCK_BUILD_ROOT/lib +cp $ATHENA/build/ext/makefiles/quazip/project/lib/libquazip5.so.*.*.* $DOCK_BUILD_ROOT/lib +chmod +x $DOCK_BUILD_ROOT/lib/* +strip --strip-all $DOCK_BUILD_ROOT/lib/* +chrpath -d $DOCK_BUILD_ROOT/lib/* +ldconfig -n $DOCK_BUILD_ROOT/lib + +SOFILES=`ls $DOCK_BUILD_ROOT/lib | sed 's/\./\\\./g' | paste -d'|' -s` +DEPENDS=`find $DOCK_BUILD_ROOT/opt $DOCK_BUILD_ROOT/lib -type f -executable -exec sh -c 'objdump -p {} | grep NEEDED' \; | awk '{print $2}' | sort | uniq | egrep -v "^($SOFILES)$" | xargs -n 1 -I {} sh -c 'dpkg -S {} | head -n 1' | cut -d ':' -f 1 | sort | uniq | paste -d' ' -s` + +cd $DOCK_BUILD_ROOT +docker build -t odysseus654/athena-server --build-arg "DEPENDS=$DEPENDS" --build-arg "GITSRC=$GITSRC" --build-arg "GITDATE=$GITDATE" --build-arg "GITCOMMIT=$GITCOMMIT" . diff --git a/pkg-scripts/make-rpm-server b/pkg-scripts/make-rpm-server new file mode 100755 index 0000000000..9863faa0ab --- /dev/null +++ b/pkg-scripts/make-rpm-server @@ -0,0 +1,56 @@ +#!/bin/sh + +if [ "$ATHENA" = "" ]; then + ATHENA=`realpath ../..` +fi +GITDATE=`git -C $ATHENA/source log -n 1 --format=raw | grep author | cut -d">" -f 2 | cut -d" " -f 2 | xargs -I {} date -d @{} +"%Y%m%d"` +GITCOMMIT=`git -C $ATHENA/source rev-parse HEAD | cut -c 1-7` +VERSION=0.86.0_K2_${GITDATE}_${GITCOMMIT} + +SOFILES=`ls \ + $ATHENA/build/libraries/*/*.so \ + $ATHENA/qt5-install/lib/libQt5Network.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Core.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Widgets.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Gui.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Script.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Quick.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5WebSockets.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Qml.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5ScriptTools.so.*.*.* \ + $ATHENA/build/ext/makefiles/quazip/project/lib/libquazip5.so.*.*.* \ + | sed 's/\./\\\./g' \ + | paste -d'|' -s` + +DEPENDS=mesa-libGL,`ls \ + $ATHENA/build/assignment-client/assignment-client \ + $ATHENA/build/domain-server/domain-server \ + $ATHENA/build/tools/oven/oven \ + $ATHENA/build/libraries/*/*.so \ + $ATHENA/qt5-install/lib/libQt5Network.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Core.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Widgets.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Gui.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Script.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Quick.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5WebSockets.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5Qml.so.*.*.* \ + $ATHENA/qt5-install/lib/libQt5ScriptTools.so.*.*.* \ + $ATHENA/build/ext/makefiles/quazip/project/lib/libquazip5.so.*.*.* \ + $ATHENA/build/assignment-client/plugins/*.so \ + $ATHENA/build/assignment-client/plugins/*/*.so \ + | xargs -I {} sh -c 'objdump -p {} | grep NEEDED' \ + | awk '{print $2}' \ + | sort | uniq \ + | egrep -v "^($SOFILES)$" \ + | grep -v ^libGL \ + | xargs -I {} sh -c "ldconfig -p | grep {} | tr ' ' '\n' | grep /" \ + | xargs rpm -qf --queryformat "%{NAME}\n" \ + | sort | uniq \ + | paste -d',' -s` + +sudo yum install chrpath + +export VERSION DEPENDS ATHENA +rpmbuild --target x86_64 -bb ./athena-server.spec +mv ~/rpmbuild/RPMS/x86_64/*.rpm . diff --git a/pkg-scripts/new-server b/pkg-scripts/new-server new file mode 100755 index 0000000000..fd9ba95761 --- /dev/null +++ b/pkg-scripts/new-server @@ -0,0 +1,49 @@ +#!/bin/sh +if [ -z "$1" ] || [ -z "$2" ]; then + echo "new-server {name} {base-port}" + echo + echo "Sets up a new athena server with the specified name and base port number" + echo " {name} - a simple name used to identify the server to scripts (not used in the server configuration)" + echo " {base-port} - the base port number (default server is 40100). The metaverse port will be {base-port}+2" + echo " Four contiguous port numbers are allocated, these must not overlap with other running services on this machine" + echo + echo "Launching a server created by this script is done with:" + echo " sudo systemctl start athena-server@{name}.target" + echo + exit 1 +fi + +if [ "$(id -u)" -ne 0 ]; then + echo "new-server {name} {base-port}" + echo + echo 'This script must be run by root' >&2 + exit 1 +fi + +if [ -d "/var/lib/athena/$1" ]; then + echo "Path /var/lib/athena/$1 already exists" + echo + echo "Please remove this path first if you wish to recreate this server" + exit 2 +fi + +mkdir -p /var/lib/athena/$1/.local/share +ln -s ../.. /var/lib/athena/$1/.local/share/Project\ Athena\ -\ dev +ln -s ../.. /var/lib/athena/$1/.local/share/Project\ Athena +mkdir -p /var/lib/athena/$1/domain-server +echo "{\"metaverse\": {\"local_port\": $(($2 + 2))},\"version\": 2.4}" > /var/lib/athena/$1/domain-server/config.json +chown -R athena.athena /var/lib/athena/$1 + +echo HIFI_DOMAIN_SERVER_HTTP_PORT=$2 > /etc/opt/athena/$1.conf +echo HIFI_DOMAIN_SERVER_HTTPS_PORT=$(($2 + 1)) >> /etc/opt/athena/$1.conf +echo HIFI_DOMAIN_SERVER_PORT=$(($2 + 2)) >> /etc/opt/athena/$1.conf +echo HIFI_DOMAIN_SERVER_DTLS_PORT=$(($2 + 3)) >> /etc/opt/athena/$1.conf + +echo "A new athena server has been created with the name of '$1'" +echo +echo "To launch it:" +echo " sudo systemctl start athena-server@$1.target" +echo "To have it launch at system start:" +echo " sudo systemctl enable athena-server@$1.target" +echo "The server configuration console is available at:" +echo " http://localhost:$2" diff --git a/pkg-scripts/server-control b/pkg-scripts/server-control new file mode 100644 index 0000000000..70383891bd --- /dev/null +++ b/pkg-scripts/server-control @@ -0,0 +1,15 @@ +Source: athena-server +Section: comm +Priority: optional +Maintainer: Heather Anderson +Build-Depends: debhelper (>= 10) +Standards-Version: 4.1.2 +Homepage: https://www.projectathena.dev +Vcs-Git: https://github.com/kasenvr/project-athena.git +Vcs-Browser: https://github.com/kasenvr/project-athena + +Package: athena-server +Architecture: any +Depends: adduser, {DEPENDS} +Description: Project Athena allows creation and sharing of VR experiences. + The Project Athena metaverse provides built-in social features, including avatar interactions, spatialized audio and interactive physics. Additionally, you have the ability to import any 3D object into your virtual environment. diff --git a/pkg-scripts/server-postinst b/pkg-scripts/server-postinst new file mode 100755 index 0000000000..fa14e8175f --- /dev/null +++ b/pkg-scripts/server-postinst @@ -0,0 +1,53 @@ +#!/bin/sh +# postinst script for athena-server +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure) + ldconfig -n /opt/athena/lib + adduser --system --quiet --gecos "Project Athena" --home /var/lib/athena --group --no-create-home athena + mkdir -p /var/lib/athena + chown athena:athena /var/lib/athena + chmod 775 /var/lib/athena + if [ ! -d "/var/lib/athena/default" ]; then + /opt/athena/new-server default 40100 + systemctl enable athena-server@default.target + systemctl start athena-server@default.target + fi + ;; + + abort-remove|abort-deconfigure) + ldconfig -n /opt/athena/lib + ;; + + abort-upgrade) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/pkg-scripts/server-prerm b/pkg-scripts/server-prerm new file mode 100755 index 0000000000..cdeddd308e --- /dev/null +++ b/pkg-scripts/server-prerm @@ -0,0 +1,42 @@ +#!/bin/sh +# prerm script for athena-server +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `upgrade' +# * `failed-upgrade' +# * `remove' `in-favour' +# * `deconfigure' `in-favour' +# `removing' +# +# for details, see https://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + remove) + find -P /opt/athena/lib -type l -delete + ;; + + upgrade|deconfigure) + ;; + + failed-upgrade) + ;; + + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/pkg-scripts/server-rules b/pkg-scripts/server-rules new file mode 100755 index 0000000000..4585591b15 --- /dev/null +++ b/pkg-scripts/server-rules @@ -0,0 +1,55 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +%: + dh $@ --with=systemd + +override_dh_systemd_enable: + dh_systemd_enable --no-enable --name athena-assignment-client athena-assignment-client.service + dh_systemd_enable --no-enable --name athena-assignment-client@ athena-assignment-client@.service + dh_systemd_enable --no-enable --name athena-domain-server athena-domain-server.service + dh_systemd_enable --no-enable --name athena-domain-server@ athena-domain-server@.service + #dh_systemd_enable --no-enable --name athena-ice-server athena-ice-server.service + #dh_systemd_enable --no-enable --name athena-ice-server@ athena-ice-server@.service + dh_systemd_enable --no-enable --name athena-server athena-server.target + dh_systemd_enable --no-enable --name athena-server@ athena-server@.target + #dh_systemd_enable --name athena-server@default athena-server@default.target + +override_dh_systemd_start: + dh_systemd_start --restart-after-upgrade --no-start athena-assignment-client.service + dh_systemd_start --restart-after-upgrade --no-start athena-assignment-client@.service + dh_systemd_start --restart-after-upgrade --no-start athena-domain-server.service + dh_systemd_start --restart-after-upgrade --no-start athena-domain-server@.service + #dh_systemd_start --restart-after-upgrade --no-start athena-ice-server.service + #dh_systemd_start --restart-after-upgrade --no-start athena-ice-server@.service + dh_systemd_start --restart-after-upgrade --no-start athena-server.target + dh_systemd_start --restart-after-upgrade --no-start athena-server@.target + #dh_systemd_start --restart-after-upgrade athena-server@default.target + +override_dh_installinit: + dh_installinit --noscripts + +override_dh_shlibdeps: + # don't run sh_shlibdeps, it REALLY won't work. We do it ourselves anyhow + +override_dh_strip: + # don't run dh_strip, we do it ourselves anyhow and we want failures to be non-fatal + +# dh_make generated override targets +# This is example for Cmake (See https://bugs.debian.org/641051 ) +#override_dh_auto_configure: +# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index b17be50c39..1448e14c72 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -9,7 +9,7 @@ # add the plugin directories file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") - +set(CMAKE_BUILD_TYPE "Release") # client-side plugins if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "oculus") @@ -25,7 +25,7 @@ if (NOT SERVER_ONLY AND NOT ANDROID) set(DIR "hifiSixense") add_subdirectory(${DIR}) endif() - + set(DIR "hifiSpacemouse") add_subdirectory(${DIR}) set(DIR "hifiNeuron") @@ -49,6 +49,8 @@ set(DIR "pcmCodec") add_subdirectory(${DIR}) set(DIR "hifiCodec") add_subdirectory(${DIR}) +set(DIR "opusCodec") +add_subdirectory(${DIR}) # example plugins set(DIR "KasenAPIExample") diff --git a/plugins/hifiCodec/CMakeLists.txt b/plugins/hifiCodec/CMakeLists.txt index 0d4f093fc2..5515602d2f 100644 --- a/plugins/hifiCodec/CMakeLists.txt +++ b/plugins/hifiCodec/CMakeLists.txt @@ -8,7 +8,7 @@ set(TARGET_NAME hifiCodec) setup_hifi_client_server_plugin() -link_hifi_libraries(audio plugins) +link_hifi_libraries(shared audio plugins) target_hifiAudioCodec() if (BUILD_SERVER) install_beside_console() diff --git a/plugins/hifiCodec/src/HiFiCodec.cpp b/plugins/hifiCodec/src/HiFiCodec.cpp index 99bb411539..a93e6c47d0 100644 --- a/plugins/hifiCodec/src/HiFiCodec.cpp +++ b/plugins/hifiCodec/src/HiFiCodec.cpp @@ -13,6 +13,7 @@ #include #include +#include const char* HiFiCodec::NAME { "hifiAC" }; @@ -44,6 +45,8 @@ public: } virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override { + PerformanceTimer perfTimer("HiFiEncoder::encode"); + encodedBuffer.resize(_encodedSize); AudioEncoder::process((const int16_t*)decodedBuffer.constData(), (int16_t*)encodedBuffer.data(), AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); } @@ -58,11 +61,15 @@ public: } virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override { + PerformanceTimer perfTimer("HiFiEncoder::decode"); + decodedBuffer.resize(_decodedSize); AudioDecoder::process((const int16_t*)encodedBuffer.constData(), (int16_t*)decodedBuffer.data(), AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL, true); } virtual void lostFrame(QByteArray& decodedBuffer) override { + PerformanceTimer perfTimer("HiFiEncoder::lostFrame"); + decodedBuffer.resize(_decodedSize); // this performs packet loss interpolation AudioDecoder::process(nullptr, (int16_t*)decodedBuffer.data(), AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL, false); diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 108431a8ac..ce60719d67 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -108,9 +108,11 @@ QString getVrSettingString(const char* section, const char* setting) { return result; } +bool isHMDInErrorState = false; + vr::IVRSystem* acquireOpenVrSystem() { bool hmdPresent = vr::VR_IsHmdPresent(); - if (hmdPresent) { + if (hmdPresent && !isHMDInErrorState) { Lock lock(mutex); if (!activeHmd) { #if DEV_BUILD @@ -122,6 +124,14 @@ vr::IVRSystem* acquireOpenVrSystem() { #if DEV_BUILD qCDebug(displayplugins) << "OpenVR display: HMD is " << activeHmd << " error is " << eError; #endif + + if (eError == vr::VRInitError_Init_HmdNotFound) { + isHMDInErrorState = true; + activeHmd = nullptr; + #if DEV_BUILD + qCDebug(displayplugins) << "OpenVR: No HMD connected, setting nullptr!"; + #endif + } } if (activeHmd) { #if DEV_BUILD diff --git a/plugins/opusCodec/CMakeLists.txt b/plugins/opusCodec/CMakeLists.txt new file mode 100644 index 0000000000..583aff85d6 --- /dev/null +++ b/plugins/opusCodec/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# Created by Michael Bailey on 12/20/2019 +# Copyright 2019 Michael Bailey +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html +# + +set(TARGET_NAME opusCodec) +setup_hifi_client_server_plugin() +link_hifi_libraries(shared audio plugins) +target_opus() + +if (BUILD_SERVER) + install_beside_console() +endif () diff --git a/plugins/opusCodec/src/OpusCodecManager.cpp b/plugins/opusCodec/src/OpusCodecManager.cpp new file mode 100644 index 0000000000..1e3d73a229 --- /dev/null +++ b/plugins/opusCodec/src/OpusCodecManager.cpp @@ -0,0 +1,58 @@ +// +// opusCodec.cpp +// plugins/opusCodec/src +// +// Created by Michael Bailey on 12/20/2019 +// Copyright 2019 Michael Bailey +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "OpusCodecManager.h" + +#include + +#include + +#include "OpusEncoder.h" +#include "OpusDecoder.h" + +const char* AthenaOpusCodec::NAME { "opus" }; + +void AthenaOpusCodec::init() { +} + +void AthenaOpusCodec::deinit() { +} + +bool AthenaOpusCodec::activate() { + CodecPlugin::activate(); + return true; +} + +void AthenaOpusCodec::deactivate() { + CodecPlugin::deactivate(); +} + + +bool AthenaOpusCodec::isSupported() const { + return true; +} + + +Encoder* AthenaOpusCodec::createEncoder(int sampleRate, int numChannels) { + return new AthenaOpusEncoder(sampleRate, numChannels); +} + +Decoder* AthenaOpusCodec::createDecoder(int sampleRate, int numChannels) { + return new AthenaOpusDecoder(sampleRate, numChannels); +} + +void AthenaOpusCodec::releaseEncoder(Encoder* encoder) { + delete encoder; +} + +void AthenaOpusCodec::releaseDecoder(Decoder* decoder) { + delete decoder; +} diff --git a/plugins/opusCodec/src/OpusCodecManager.h b/plugins/opusCodec/src/OpusCodecManager.h new file mode 100644 index 0000000000..be6a6b2ff0 --- /dev/null +++ b/plugins/opusCodec/src/OpusCodecManager.h @@ -0,0 +1,42 @@ +// +// OpusCodecManager.h +// plugins/opusCodec/src +// +// Created by Michael Bailey on 12/20/2019 +// Copyright 2019 Michael Bailey +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi__OpusCodecManager_h +#define hifi__OpusCodecManager_h + +#include + +class AthenaOpusCodec : public CodecPlugin { + Q_OBJECT + +public: + // Plugin functions + bool isSupported() const override; + const QString getName() const override { return NAME; } + + void init() override; + void deinit() override; + + /// Called when a plugin is being activated for use. May be called multiple times. + bool activate() override; + /// Called when a plugin is no longer being used. May be called multiple times. + void deactivate() override; + + virtual Encoder* createEncoder(int sampleRate, int numChannels) override; + virtual Decoder* createDecoder(int sampleRate, int numChannels) override; + virtual void releaseEncoder(Encoder* encoder) override; + virtual void releaseDecoder(Decoder* decoder) override; + +private: + static const char* NAME; +}; + +#endif // hifi__opusCodecManager_h diff --git a/plugins/opusCodec/src/OpusCodecProvider.cpp b/plugins/opusCodec/src/OpusCodecProvider.cpp new file mode 100644 index 0000000000..79f01de4bd --- /dev/null +++ b/plugins/opusCodec/src/OpusCodecProvider.cpp @@ -0,0 +1,45 @@ +// +// Created by Michael Bailey on 12/20/2019 +// Copyright 2019 Michael Bailey +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include +#include +#include + +#include +#include + +#include "OpusCodecManager.h" + +class AthenaOpusCodecProvider : public QObject, public CodecProvider { + Q_OBJECT + Q_PLUGIN_METADATA(IID CodecProvider_iid FILE "plugin.json") + Q_INTERFACES(CodecProvider) + +public: + AthenaOpusCodecProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~AthenaOpusCodecProvider() {} + + virtual CodecPluginList getCodecPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + + CodecPluginPointer opusCodec(new AthenaOpusCodec()); + if (opusCodec->isSupported()) { + _codecPlugins.push_back(opusCodec); + } + }); + return _codecPlugins; + } + +private: + CodecPluginList _codecPlugins; +}; + +#include "OpusCodecProvider.moc" diff --git a/plugins/opusCodec/src/OpusDecoder.cpp b/plugins/opusCodec/src/OpusDecoder.cpp new file mode 100644 index 0000000000..e3e4e3645a --- /dev/null +++ b/plugins/opusCodec/src/OpusDecoder.cpp @@ -0,0 +1,131 @@ +// +// OpusCodecManager.h +// plugins/opusCodec/src +// +// Copyright 2020 Dale Glass +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include + +#include "OpusDecoder.h" + +static QLoggingCategory decoder("AthenaOpusDecoder"); + +static QString error_to_string(int error) { + switch (error) { + case OPUS_OK: + return "OK"; + case OPUS_BAD_ARG: + return "One or more invalid/out of range arguments."; + case OPUS_BUFFER_TOO_SMALL: + return "The mode struct passed is invalid."; + case OPUS_INTERNAL_ERROR: + return "An internal error was detected."; + case OPUS_INVALID_PACKET: + return "The compressed data passed is corrupted."; + case OPUS_UNIMPLEMENTED: + return "Invalid/unsupported request number."; + case OPUS_INVALID_STATE: + return "An encoder or decoder structure is invalid or already freed."; + default: + return QString("Unknown error code: %i").arg(error); + } +} + + +AthenaOpusDecoder::AthenaOpusDecoder(int sampleRate, int numChannels) { + int error; + + _opusSampleRate = sampleRate; + _opusNumChannels = numChannels; + + _decoder = opus_decoder_create(sampleRate, numChannels, &error); + + if (error != OPUS_OK) { + qCCritical(decoder) << "Failed to initialize Opus encoder: " << error_to_string(error); + _decoder = nullptr; + return; + } + + + qCDebug(decoder) << "Opus decoder initialized, sampleRate = " << sampleRate << "; numChannels = " << numChannels; +} + +AthenaOpusDecoder::~AthenaOpusDecoder() { + if (_decoder) { + opus_decoder_destroy(_decoder); + } + +} + +void AthenaOpusDecoder::decode(const QByteArray &encodedBuffer, QByteArray &decodedBuffer) { + assert(_decoder); + PerformanceTimer perfTimer("AthenaOpusDecoder::decode"); + + // The audio system encodes and decodes always in fixed size chunks + int bufferSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast(sizeof(int16_t)) + * _opusNumChannels; + + decodedBuffer.resize(bufferSize); + int bufferFrames = decodedBuffer.size() / _opusNumChannels / static_cast(sizeof(opus_int16)); + int decoded_frames = opus_decode(_decoder, reinterpret_cast(encodedBuffer.data()), + encodedBuffer.length(), reinterpret_cast(decodedBuffer.data()), bufferFrames, 0); + + if (decoded_frames >= 0) { + + if (decoded_frames < bufferFrames) { + qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << bufferFrames + << " were expected!"; + + int start = decoded_frames * static_cast(sizeof(int16_t)) * _opusNumChannels; + memset( &decodedBuffer.data()[start], 0, static_cast(decodedBuffer.length() - start)); + } else if (decoded_frames > bufferFrames) { + // This should never happen + qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << bufferFrames + << " were expected! Buffer overflow!?"; + } + } else { + qCCritical(decoder) << "Failed to decode audio: " << error_to_string(decoded_frames); + decodedBuffer.fill('\0'); + } + +} + +void AthenaOpusDecoder::lostFrame(QByteArray &decodedBuffer) { + assert(_decoder); + + PerformanceTimer perfTimer("AthenaOpusDecoder::lostFrame"); + + int bufferSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast(sizeof(int16_t)) + * _opusNumChannels; + decodedBuffer.resize(bufferSize); + int bufferFrames = decodedBuffer.size() / _opusNumChannels / static_cast(sizeof(opus_int16)); + + int decoded_frames = opus_decode(_decoder, nullptr, 0, reinterpret_cast(decodedBuffer.data()), + bufferFrames, 1); + + if (decoded_frames >= 0) { + + if ( decoded_frames < bufferFrames ) { + qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << bufferFrames + << " were expected!"; + + int start = decoded_frames * static_cast(sizeof(int16_t)) * _opusNumChannels; + memset( &decodedBuffer.data()[start], 0, static_cast(decodedBuffer.length() - start)); + } else if (decoded_frames > bufferFrames) { + // This should never happen + qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << bufferFrames + << " were expected! Buffer overflow!?"; + } + + } else { + qCCritical(decoder) << "Failed to decode lost frame: " << error_to_string(decoded_frames); + decodedBuffer.fill('\0'); + } + +} diff --git a/plugins/opusCodec/src/OpusDecoder.h b/plugins/opusCodec/src/OpusDecoder.h new file mode 100644 index 0000000000..095893856b --- /dev/null +++ b/plugins/opusCodec/src/OpusDecoder.h @@ -0,0 +1,39 @@ +// +// OpusCodecManager.h +// plugins/opusCodec/src +// +// Copyright 2020 Dale Glass +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef OPUSDECODER_H +#define OPUSDECODER_H + + +#include +#include + + +class AthenaOpusDecoder : public Decoder { +public: + AthenaOpusDecoder(int sampleRate, int numChannels); + ~AthenaOpusDecoder() override; + + + virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override; + virtual void lostFrame(QByteArray &decodedBuffer) override; + + +private: + int _encodedSize; + + OpusDecoder* _decoder = nullptr; + int _opusSampleRate = 0; + int _opusNumChannels = 0; + int _decodedSize = 0; +}; + + +#endif // OPUSDECODER_H diff --git a/plugins/opusCodec/src/OpusEncoder.cpp b/plugins/opusCodec/src/OpusEncoder.cpp new file mode 100644 index 0000000000..3408701633 --- /dev/null +++ b/plugins/opusCodec/src/OpusEncoder.cpp @@ -0,0 +1,273 @@ +// +// OpusCodecManager.h +// plugins/opusCodec/src +// +// Copyright 2020 Dale Glass +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include + +#include "OpusEncoder.h" + +static QLoggingCategory encoder("AthenaOpusEncoder"); + +static QString errorToString(int error) { + switch (error) { + case OPUS_OK: + return "OK"; + case OPUS_BAD_ARG: + return "One or more invalid/out of range arguments."; + case OPUS_BUFFER_TOO_SMALL: + return "The mode struct passed is invalid."; + case OPUS_INTERNAL_ERROR: + return "An internal error was detected."; + case OPUS_INVALID_PACKET: + return "The compressed data passed is corrupted."; + case OPUS_UNIMPLEMENTED: + return "Invalid/unsupported request number."; + case OPUS_INVALID_STATE: + return "An encoder or decoder structure is invalid or already freed."; + default: + return QString("Unknown error code: %i").arg(error); + } +} + + + +AthenaOpusEncoder::AthenaOpusEncoder(int sampleRate, int numChannels) { + _opusSampleRate = sampleRate; + _opusChannels = numChannels; + + int error; + + _encoder = opus_encoder_create(sampleRate, numChannels, DEFAULT_APPLICATION, &error); + + if (error != OPUS_OK) { + qCCritical(encoder) << "Failed to initialize Opus encoder: " << errorToString(error); + _encoder = nullptr; + return; + } + + setBitrate(DEFAULT_BITRATE); + setComplexity(DEFAULT_COMPLEXITY); + setApplication(DEFAULT_APPLICATION); + setSignal(DEFAULT_SIGNAL); + + qCDebug(encoder) << "Opus encoder initialized, sampleRate = " << sampleRate << "; numChannels = " << numChannels; +} + +AthenaOpusEncoder::~AthenaOpusEncoder() { + opus_encoder_destroy(_encoder); +} + + + +void AthenaOpusEncoder::encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) { + + PerformanceTimer perfTimer("AthenaOpusEncoder::encode"); + assert(_encoder); + + encodedBuffer.resize(decodedBuffer.size()); + int frameSize = decodedBuffer.length() / _opusChannels / static_cast(sizeof(opus_int16)); + + int bytes = opus_encode(_encoder, reinterpret_cast(decodedBuffer.constData()), frameSize, + reinterpret_cast(encodedBuffer.data()), encodedBuffer.size() ); + + if (bytes >= 0) { + encodedBuffer.resize(bytes); + } else { + encodedBuffer.resize(0); + + qCWarning(encoder) << "Error when encoding " << decodedBuffer.length() << " bytes of audio: " + << errorToString(bytes); + } + +} + +int AthenaOpusEncoder::getComplexity() const { + assert(_encoder); + int returnValue; + opus_encoder_ctl(_encoder, OPUS_GET_COMPLEXITY(&returnValue)); + return returnValue; +} + +void AthenaOpusEncoder::setComplexity(int complexity) { + assert(_encoder); + int returnValue = opus_encoder_ctl(_encoder, OPUS_SET_COMPLEXITY(complexity)); + + if (returnValue != OPUS_OK) { + qCWarning(encoder) << "Error when setting complexity to " << complexity << ": " << errorToString(returnValue); + } +} + +int AthenaOpusEncoder::getBitrate() const { + assert(_encoder); + int returnValue; + opus_encoder_ctl(_encoder, OPUS_GET_BITRATE(&returnValue)); + return returnValue; +} + +void AthenaOpusEncoder::setBitrate(int bitrate) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_BITRATE(bitrate)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting bitrate to " << bitrate << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getVBR() const { + assert(_encoder); + int returnValue; + opus_encoder_ctl(_encoder, OPUS_GET_VBR(&returnValue)); + return returnValue; +} + +void AthenaOpusEncoder::setVBR(int vbr) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_VBR(vbr)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting VBR to " << vbr << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getVBRConstraint() const { + assert(_encoder); + int returnValue; + opus_encoder_ctl(_encoder, OPUS_GET_VBR_CONSTRAINT(&returnValue)); + return returnValue; +} + +void AthenaOpusEncoder::setVBRConstraint(int vbr_const) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_VBR_CONSTRAINT(vbr_const)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting VBR constraint to " << vbr_const << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getMaxBandwidth() const { + assert(_encoder); + int returnValue; + opus_encoder_ctl(_encoder, OPUS_GET_MAX_BANDWIDTH(&returnValue)); + return returnValue; +} + +void AthenaOpusEncoder::setMaxBandwidth(int maxBandwidth) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_MAX_BANDWIDTH(maxBandwidth)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting max bandwidth to " << maxBandwidth << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getBandwidth() const { + assert(_encoder); + int bandwidth; + opus_encoder_ctl(_encoder, OPUS_GET_BANDWIDTH(&bandwidth)); + return bandwidth; +} + +void AthenaOpusEncoder::setBandwidth(int bandwidth) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_BANDWIDTH(bandwidth)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting bandwidth to " << bandwidth << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getSignal() const { + assert(_encoder); + int signal; + opus_encoder_ctl(_encoder, OPUS_GET_SIGNAL(&signal)); + return signal; +} + +void AthenaOpusEncoder::setSignal(int signal) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_SIGNAL(signal)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting signal to " << signal << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getApplication() const { + assert(_encoder); + int applicationValue; + opus_encoder_ctl(_encoder, OPUS_GET_APPLICATION(&applicationValue)); + return applicationValue; +} + +void AthenaOpusEncoder::setApplication(int application) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_APPLICATION(application)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting application to " << application << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getLookahead() const { + assert(_encoder); + int lookAhead; + opus_encoder_ctl(_encoder, OPUS_GET_LOOKAHEAD(&lookAhead)); + return lookAhead; +} + +int AthenaOpusEncoder::getInbandFEC() const { + assert(_encoder); + int fec; + opus_encoder_ctl(_encoder, OPUS_GET_INBAND_FEC(&fec)); + return fec; +} + +void AthenaOpusEncoder::setInbandFEC(int inBandFEC) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_INBAND_FEC(inBandFEC)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting inband FEC to " << inBandFEC << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getExpectedPacketLossPercentage() const { + assert(_encoder); + int lossPercentage; + opus_encoder_ctl(_encoder, OPUS_GET_PACKET_LOSS_PERC(&lossPercentage)); + return lossPercentage; +} + +void AthenaOpusEncoder::setExpectedPacketLossPercentage(int percentage) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_PACKET_LOSS_PERC(percentage)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting loss percent to " << percentage << ": " << errorToString(errorCode); + } +} + +int AthenaOpusEncoder::getDTX() const { + assert(_encoder); + int dtx; + opus_encoder_ctl(_encoder, OPUS_GET_DTX(&dtx)); + return dtx; +} + +void AthenaOpusEncoder::setDTX(int dtx) { + assert(_encoder); + int errorCode = opus_encoder_ctl(_encoder, OPUS_SET_DTX(dtx)); + + if (errorCode != OPUS_OK) { + qCWarning(encoder) << "Error when setting DTX to " << dtx << ": " << errorToString(errorCode); + } +} diff --git a/plugins/opusCodec/src/OpusEncoder.h b/plugins/opusCodec/src/OpusEncoder.h new file mode 100644 index 0000000000..10640bf409 --- /dev/null +++ b/plugins/opusCodec/src/OpusEncoder.h @@ -0,0 +1,78 @@ +// +// OpusCodecManager.h +// plugins/opusCodec/src +// +// Copyright 2020 Dale Glass +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef OPUSENCODER_H +#define OPUSENCODER_H +#include +#include + + +class AthenaOpusEncoder : public Encoder { +public: + + AthenaOpusEncoder(int sampleRate, int numChannels); + ~AthenaOpusEncoder() override; + + virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override; + + + int getComplexity() const; + void setComplexity(int complexity); + + int getBitrate() const; + void setBitrate(int bitrate); + + int getVBR() const; + void setVBR(int vbr); + + int getVBRConstraint() const; + void setVBRConstraint(int vbrConstraint); + + int getMaxBandwidth() const; + void setMaxBandwidth(int maxBandwidth); + + int getBandwidth() const; + void setBandwidth(int bandwidth); + + int getSignal() const; + void setSignal(int signal); + + int getApplication() const; + void setApplication(int application); + + int getLookahead() const; + + int getInbandFEC() const; + void setInbandFEC(int inBandFEC); + + int getExpectedPacketLossPercentage() const; + void setExpectedPacketLossPercentage(int percentage); + + int getDTX() const; + void setDTX(int dtx); + + +private: + + const int DEFAULT_BITRATE = 128000; + const int DEFAULT_COMPLEXITY = 10; + const int DEFAULT_APPLICATION = OPUS_APPLICATION_VOIP; + const int DEFAULT_SIGNAL = OPUS_AUTO; + + int _opusSampleRate = 0; + int _opusChannels = 0; + int _opusExpectedLoss = 0; + + + OpusEncoder* _encoder = nullptr; +}; + + +#endif // OPUSENCODER_H diff --git a/plugins/opusCodec/src/plugin.json b/plugins/opusCodec/src/plugin.json new file mode 100644 index 0000000000..17217d6017 --- /dev/null +++ b/plugins/opusCodec/src/plugin.json @@ -0,0 +1,4 @@ +{ + "name": "Opus Codec", + "version": 1 +} diff --git a/prebuild.py b/prebuild.py index 089cb0b903..03677f21d7 100644 --- a/prebuild.py +++ b/prebuild.py @@ -125,7 +125,7 @@ def main(): if 'Windows' == system and 'CI_BUILD' in os.environ and os.environ["CI_BUILD"] == "Github": logger.info("Downloading NSIS") with timer('NSIS'): - hifi_utils.downloadAndExtract('https://hifi-public.s3.amazonaws.com/dependencies/NSIS-hifi-plugins-1.0.tgz', "C:/Program Files (x86)") + hifi_utils.downloadAndExtract('https://athena-public.s3.amazonaws.com/dependencies/NSIS-hifi-plugins-1.0.tgz', "C:/Program Files (x86)") qtInstallPath = '' # If not android, install our Qt build @@ -137,8 +137,11 @@ def main(): qt.installQt() qt.writeConfig() - # Only allow one instance of the program to run at a time pm = hifi_vcpkg.VcpkgRepo(args) + if qtInstallPath != '': + pm.writeVar('QT_CMAKE_PREFIX_PATH', qtInstallPath) + + # Only allow one instance of the program to run at a time with hifi_singleton.Singleton(pm.lockFile) as lock: with timer('Bootstraping'): diff --git a/script-archive/tests/performance/renderableMatrix.js b/script-archive/tests/performance/renderableMatrix.js index dd0fd6e54d..04946328cc 100644 --- a/script-archive/tests/performance/renderableMatrix.js +++ b/script-archive/tests/performance/renderableMatrix.js @@ -114,7 +114,7 @@ Script.setInterval(function () { if (isModel) { properties.modelURL = type; } else if (type === 'Web') { - properties.sourceUrl = 'https://highfidelity.com'; + properties.sourceUrl = 'https://projectathena.io'; } else { properties.color = { red: x / ROWS_X * 255, green: y / ROWS_Y * 255, blue: z / ROWS_Z * 255 }; if (type === 'ParticleEffect') { diff --git a/scripts/communityModules/chat/FloofChat.html b/scripts/communityModules/chat/FloofChat.html new file mode 100644 index 0000000000..a1e84e132f --- /dev/null +++ b/scripts/communityModules/chat/FloofChat.html @@ -0,0 +1,471 @@ + + + + + + Title + + + + + + + + + + + + + +
    +
    + + + +
    + +
    + + + + Redock +
    +
    +
    +
    + +
    + + + + + + + diff --git a/scripts/communityModules/chat/FloofChat.js b/scripts/communityModules/chat/FloofChat.js new file mode 100644 index 0000000000..905dbeaafa --- /dev/null +++ b/scripts/communityModules/chat/FloofChat.js @@ -0,0 +1,591 @@ +/* globals OverlayWindow */ +"use strict"; + +// +// FloofChat.js +// +// Created by Fluffy Jenkins January 2020. +// Copyright 2020 Fluffy Jenkins +// +// For any future coders, please keep me in the loop when making changes. +// Please tag me in any Pull Requests. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var ROOT = Script.resolvePath('').split("FloofChat.js")[0]; +var H_KEY = 72; +var ENTER_KEY = 16777220; +var ESC_KEY = 16777216; +var CONTROL_KEY = 67108864; +var SHIFT_KEY = 33554432; +var FLOOF_CHAT_CHANNEL = "Chat"; +var FLOOF_NOTIFICATION_CHANNEL = "Floof-Notif"; + +Script.scriptEnding.connect(function () { + shutdown(); +}); + +var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); +var button = tablet.addButton({ + icon: ROOT + "chat.png", + text: "CHAT" +}); + +Script.scriptEnding.connect(function () { // So if anything errors out the tablet/toolbar button gets removed! + tablet.removeButton(button); +}); + +var appUUID = Uuid.generate(); + +var chatBar; +var chatHistory; +var chatBarHistoryLimit = Settings.getValue(settingsRoot + "/chatBarHistoryLimit", 256); +var chatHistoryLimit = Settings.getValue(settingsRoot + "/chatHistoryLimit", 500); +var chatBarHistory = Settings.getValue(settingsRoot + "/chatBarHistory", ["Meow :3"]); +var historyLog = []; + +var visible = false; +var historyVisible = false; +var settingsRoot = "FloofChat"; + +var athenaGotoUrl = "https://metaverse.projectathena.io/interim/d-goto/app/goto.json"; +var gotoJSONUrl = Settings.getValue(settingsRoot + "/gotoJSONUrl", athenaGotoUrl); + +var muted = Settings.getValue(settingsRoot + "/muted", {"Local": false, "Domain": false, "Grid": false}); + +var ws; +var wsReady = false; +var WEB_SOCKET_URL = "ws://chat.projectathena.io:8880"; // WebSocket for Grid chat. +var shutdownBool = false; + +var defaultColour = {red: 255, green: 255, blue: 255}; +var colours = {}; +colours["localChatColour"] = Settings.getValue(settingsRoot + "/localChatColour", defaultColour); +colours["domainChatColour"] = Settings.getValue(settingsRoot + "/domainChatColour", defaultColour); +colours["gridChatColour"] = Settings.getValue(settingsRoot + "/gridChatColour", defaultColour); + +init(); + +function init() { + Messages.subscribe(FLOOF_CHAT_CHANNEL); + historyLog = []; + try { + historyLog = JSON.parse(Settings.getValue(settingsRoot + "/HistoryLog", "[]")); + } catch (e) { + // + } + + setupHistoryWindow(false); + + chatBar = new OverlayWindow({ + source: Paths.defaultScripts + '/communityModules/chat/FloofChat.qml?' + Date.now(), + width: 360, + height: 180 + }); + + button.clicked.connect(toggleChatHistory); + chatBar.fromQml.connect(fromQml); + chatBar.sendToQml(JSON.stringify({visible: false, history: chatBarHistory})); + Controller.keyPressEvent.connect(keyPressEvent); + Messages.messageReceived.connect(messageReceived); + + connectWebSocket(); +} + +function connectWebSocket(timeout) { + ws = new WebSocket(WEB_SOCKET_URL); + ws.onmessage = function incoming(_data) { + var message = _data.data; + var cmd = {FAILED: true}; + try { + cmd = JSON.parse(message); + } catch (e) { + // + } + if (!cmd.FAILED) { + addToLog(cmd.message, cmd.displayName, cmd.colour, cmd.channel); + if (!muted["Grid"]) { + Messages.sendLocalMessage(FLOOF_NOTIFICATION_CHANNEL, JSON.stringify({ + sender: "(G) " + cmd.displayName, + text: replaceFormatting(cmd.message), + colour: {text: cmd.colour} + })); + } + } + }; + + ws.onopen = function open() { + wsReady = true; + }; + + ws.onclose = function close() { + wsReady = false; + console.log('disconnected'); + + timeout = timeout | 0; + if (!shutdownBool) { + if (timeout > (30 * 1000)) { + timeout = 30 * 1000; + } else if (timeout < (30 * 1000)) { + timeout += 1000; + } + Script.setTimeout(function () { + connectWebSocket(timeout); + }, timeout); + } else { + wsReady = -1; + } + }; +} + + +function sendWS(msg, timeout) { + if (wsReady === true) { + ws.send(JSON.stringify(msg)); + } else { + timeout = timeout | 0; + if (!shutdownBool) { + if (timeout > (30 * 1000)) { + timeout = 30 * 1000; + } else if (timeout < (30 * 1000)) { + timeout += 1000; + } + Script.setTimeout(function () { + if (wsReady === -1) { + connectWebSocket(); + } + sendWS(msg, timeout); + }, timeout); + } + } +} + +function setupHistoryWindow() { + chatHistory = new OverlayWebWindow({ + title: 'Chat', + source: ROOT + "FloofChat.html?appUUID=" + appUUID + "&" + Date.now(), + width: 900, + height: 700, + visible: false + }); + chatHistory.setPosition({x: 0, y: Window.innerHeight - 700}); + chatHistory.webEventReceived.connect(onWebEventReceived); + chatHistory.closed.connect(toggleChatHistory); +} + +function emitScriptEvent(obj) { + obj.appUUID = appUUID; + tablet.emitScriptEvent(JSON.stringify(obj)); +} + +function toggleChatHistory() { + historyVisible = !historyVisible; + button.editProperties({isActive: historyVisible}); + chatHistory.visible = historyVisible; +} + +function chatColour(tab) { + if (tab === "Local") { + return colours["localChatColour"]; + } else if (tab === "Domain") { + return colours["domainChatColour"]; + } else if (tab === "Grid") { + return colours["gridChatColour"]; + } else { + return defaultColour; + } +} + +var chatBarChannel = "Local"; + +function go2(msg) { + var dest = false; + var domainsList = []; + try { + domainsList = Script.require(gotoJSONUrl + "?" + Date.now()); + } catch (e) { + // + } + domainsList.forEach(function (domain) { + if (domain["Domain Name"].toLowerCase().indexOf(msg.toLowerCase()) !== -1 && !dest) { + dest = {"name": domain["Domain Name"], "url": domain["Visit"]}; + } + }); + return dest; +} + +function gotoConfirm(url, name, confirm) { + confirm = confirm === undefined ? true : confirm; + name = name === undefined ? url : name; + var result = true; + if (confirm) { + result = Window.confirm("Do you want to go to '" + ((name.indexOf("/") !== -1) ? url.split("/")[2] : name) + "'?"); + } + if (result) { + location = url; + } +} + +function processChat(cmd) { + + function commandResult() { + msg = ""; + setVisible(false); + } + + var msg = cmd.message; + if (msg.indexOf("/") === 0) { + msg = msg.substring(1); + var commandList = msg.split(" "); + var tempList = commandList.concat(); + tempList.shift(); + var restOfMsg = tempList.join(" "); + + msg = "/" + msg; + var cmd1 = commandList[0].toLowerCase(); + if (cmd1 === "l") { + chatBarChannel = "Local"; + commandResult(); + } + if (cmd1 === "d") { + chatBarChannel = "Domain"; + commandResult(); + } + if (cmd1 === "g") { + chatBarChannel = "Grid"; + commandResult(); + } + + if (cmd1 === "goto" || cmd1 === "gotos") { + var result = go2(restOfMsg); + if (result) { + gotoConfirm(result.url, result.name, (cmd1 === "goto")); + } else { + gotoConfirm(commandList[1], undefined, (cmd1 === "goto")); + } + commandResult(); + } + + if (cmd1 === "me") { + msg = cmd.avatarName + " " + restOfMsg; + cmd.avatarName = ""; + } + } + cmd.message = msg; + return cmd; +} + +function onWebEventReceived(event) { + event = JSON.parse(event); + if (event.type === "ready") { + chatHistory.emitScriptEvent(JSON.stringify({type: "MSG", data: historyLog})); + chatHistory.emitScriptEvent(JSON.stringify({type: "CMD", cmd: "MUTED", muted: muted})); + } + if (event.type === "CMD") { + if (event.cmd === "MUTED") { + muted = event.muted; + Settings.setValue(settingsRoot + "/muted", muted); + } + if (event.cmd === "COLOUR") { + Settings.setValue(settingsRoot + "/" + event.colourType + "Colour", event.colour); + colours[event.colourType] = event.colour; + } + if (event.cmd === "REDOCK") { + chatHistory.setPosition({x: 0, y: Window.innerHeight - 700}); + } + if (event.cmd === "GOTO") { + gotoConfirm(event.url); + } + if (event.cmd === "URL") { + new OverlayWebWindow({ + title: 'Web', + source: event.url, + width: 900, + height: 700, + visible: true + }); + } + if (event.cmd === "COPY") { + Window.copyToClipboard(event.url); + } + } + if (event.type === "WEBMSG") { + event.avatarName = MyAvatar.displayName; + event = processChat(event); + if (event.message === "") return; + sendWS({ + uuid: "", + type: "WebChat", + channel: event.tab, + colour: chatColour(event.tab), + message: event.message, + displayName: event.avatarName + }); + } + if (event.type === "MSG") { + event.avatarName = MyAvatar.displayName; + event = processChat(event); + if (event.message === "") return; + Messages.sendMessage("Chat", JSON.stringify({ + type: "TransmitChatMessage", + position: MyAvatar.position, + channel: event.tab, + colour: chatColour(event.tab), + message: event.message, + displayName: event.avatarName + })); + setVisible(false); + } +} + +function replaceFormatting(text) { + var found = false; + if (text.indexOf("**") !== -1) { + var firstMatch = text.indexOf("**") + 2; + var secondMatch = text.indexOf("**", firstMatch); + if (firstMatch !== -1 && secondMatch !== -1) { + found = true; + var part1 = text.substring(0, firstMatch - 2); + var part2 = text.substring(firstMatch, secondMatch); + var part3 = text.substring(secondMatch + 2); + text = part1 + "" + part2 + "" + part3; + } + } else if (text.indexOf("*") !== -1) { + var firstMatch = text.indexOf("*") + 1; + var secondMatch = text.indexOf("*", firstMatch); + if (firstMatch !== -1 && secondMatch !== -1) { + found = true; + var part1 = text.substring(0, firstMatch - 1); + var part2 = text.substring(firstMatch, secondMatch); + var part3 = text.substring(secondMatch + 1); + text = part1 + "" + part2 + "" + part3; + } + } else if (text.indexOf("__") !== -1) { + var firstMatch = text.indexOf("__") + 2; + var secondMatch = text.indexOf("__", firstMatch); + if (firstMatch !== -1 && secondMatch !== -1) { + found = true; + var part1 = text.substring(0, firstMatch - 2); + var part2 = text.substring(firstMatch, secondMatch); + var part3 = text.substring(secondMatch + 2); + text = part1 + "" + part2 + "" + part3; + } + } else if (text.indexOf("_") !== -1) { + var firstMatch = text.indexOf("_") + 1; + var secondMatch = text.indexOf("_", firstMatch); + if (firstMatch !== -1 && secondMatch !== -1) { + found = true; + var part1 = text.substring(0, firstMatch - 1); + var part2 = text.substring(firstMatch, secondMatch); + var part3 = text.substring(secondMatch + 1); + text = part1 + "" + part2 + "" + part3; + } + } else if (text.indexOf("~~") !== -1) { + var firstMatch = text.indexOf("~~") + 2; + var secondMatch = text.indexOf("~~", firstMatch); + if (firstMatch !== -1 && secondMatch !== -1) { + found = true; + var part1 = text.substring(0, firstMatch - 2); + var part2 = text.substring(firstMatch, secondMatch); + var part3 = text.substring(secondMatch + 2); + text = part1 + "" + part2 + "" + part3; + } + } + if (found) { + return replaceFormatting(text); + } else { + return text; + } +} + +function messageReceived(channel, message) { + if (channel === "Chat") { + var cmd = {FAILED: true}; + try { + cmd = JSON.parse(message); + } catch (e) { + // + } + if (!cmd.FAILED) { + if (cmd.type === "TransmitChatMessage") { + if (!cmd.hasOwnProperty("channel")) { + cmd.channel = "Domain"; + } + if (!cmd.hasOwnProperty("colour")) { + cmd.colour = {red: 222, green: 222, blue: 222}; + } + if (cmd.message.indexOf("/me") === 0) { + cmd.message = cmd.message.replace("/me", cmd.displayName); + cmd.displayName = ""; + } + if (cmd.channel === "Local") { + if (Vec3.withinEpsilon(MyAvatar.position, cmd.position, 20)) { + addToLog(cmd.message, cmd.displayName, cmd.colour, cmd.channel); + if (!muted["Local"]) { + Messages.sendLocalMessage(FLOOF_NOTIFICATION_CHANNEL, JSON.stringify({ + sender: "(L) " + cmd.displayName, + text: replaceFormatting(cmd.message), + colour: {text: cmd.colour} + })); + } + } + } else if (cmd.channel === "Domain") { + addToLog(cmd.message, cmd.displayName, cmd.colour, cmd.channel); + if (!muted["Domain"]) { + Messages.sendLocalMessage(FLOOF_NOTIFICATION_CHANNEL, JSON.stringify({ + sender: "(D) " + cmd.displayName, + text: replaceFormatting(cmd.message), + colour: {text: cmd.colour} + })); + } + } else if (cmd.channel === "Grid") { + addToLog(cmd.message, cmd.displayName, cmd.colour, cmd.channel); + if (!muted["Grid"]) { + Messages.sendLocalMessage(FLOOF_NOTIFICATION_CHANNEL, JSON.stringify({ + sender: "(G) " + cmd.displayName, + text: replaceFormatting(cmd.message), + colour: {text: cmd.colour} + })); + } + } else { + addToLog(cmd.message, cmd.displayName, cmd.colour, cmd.channel); + Messages.sendLocalMessage(FLOOF_NOTIFICATION_CHANNEL, JSON.stringify({ + sender: cmd.displayName, + text: replaceFormatting(cmd.message), + colour: {text: cmd.colour} + })); + } + } + } + } +} + +function time() { + var d = new Date(); + var h = (d.getHours()).toString(); + var m = (d.getMinutes()).toString(); + var s = (d.getSeconds()).toString(); + var h2 = ("0" + h).slice(-2); + var m2 = ("0" + m).slice(-2); + var s2 = ("0" + s).slice(-2); + s2 += (d.getMilliseconds() / 1000).toFixed(2).slice(1); + return h2 + ":" + m2 + ":" + s2; +} + +function addToLog(msg, dp, colour, tab) { + historyLog.push([time(), msg, dp, colour, tab]); + chatHistory.emitScriptEvent(JSON.stringify({type: "MSG", data: [[time(), msg, dp, colour, tab]]})); + while (historyLog.length > chatHistoryLimit) { + historyLog.shift(); + } + Settings.setValue(settingsRoot + "/HistoryLog", JSON.stringify(historyLog)) +} + +function addToChatBarHistory(msg) { + chatBarHistory.unshift(msg); + while (chatBarHistory.length > chatBarHistoryLimit) { + chatBarHistory.pop(); + } + Settings.setValue(settingsRoot + "/chatBarHistory", chatBarHistory); +} + +function fromQml(message) { + var cmd = {FAILED: true}; + try { + cmd = JSON.parse(message); + } catch (e) { + // + } + if (!cmd.FAILED) { + if (cmd.type === "MSG") { + if (cmd.message !== "") { + addToChatBarHistory(cmd.message); + if (cmd.event.modifiers === CONTROL_KEY) { + cmd.avatarName = MyAvatar.displayName; + cmd = processChat(cmd); + if (cmd.message === "") return; + Messages.sendMessage(FLOOF_CHAT_CHANNEL, JSON.stringify({ + type: "TransmitChatMessage", channel: "Domain", colour: chatColour("Domain"), + message: cmd.message, + displayName: cmd.avatarName + })); + } else if (cmd.event.modifiers === CONTROL_KEY + SHIFT_KEY) { + cmd.avatarName = MyAvatar.displayName; + cmd = processChat(cmd); + if (cmd.message === "") return; + sendWS({ + uuid: "", + type: "WebChat", + channel: "Grid", + colour: chatColour("Grid"), + message: cmd.message, + displayName: cmd.avatarName + }); + } else { + cmd.avatarName = MyAvatar.displayName; + cmd = processChat(cmd); + if (cmd.message === "") return; + Messages.sendMessage(FLOOF_CHAT_CHANNEL, JSON.stringify({ + type: "TransmitChatMessage", + channel: chatBarChannel, + position: MyAvatar.position, + colour: chatColour(chatBarChannel), + message: cmd.message, + displayName: cmd.avatarName + })); + } + } + setVisible(false); + } else if (cmd.type === "CMD") { + if (cmd.cmd === "Clicked") { + toggleChatHistory() + } + } + } +} + +function setVisible(_visible) { + if (_visible) { + Messages.sendLocalMessage(FLOOF_NOTIFICATION_CHANNEL, JSON.stringify({ + type: "options", + offset: 64 + })); + chatBar.sendToQml(JSON.stringify({visible: true})); + } else { + Messages.sendLocalMessage(FLOOF_NOTIFICATION_CHANNEL, JSON.stringify({ + type: "options", + offset: -1 + })); + chatBar.sendToQml(JSON.stringify({visible: false})); + } + visible = _visible; +} + +function keyPressEvent(event) { + if (event.key === H_KEY && !event.isAutoRepeat && event.isControl) { + toggleChatHistory() + } + if (event.key === ENTER_KEY && !event.isAutoRepeat && !visible) { + setVisible(true); + } + if (event.key === ESC_KEY && !event.isAutoRepeat && visible) { + setVisible(false); + } +} + +function shutdown() { + try { + Messages.messageReceived.disconnect(messageReceived); + } catch (e) { + // empty + } + try { + Controller.keyPressEvent.disconnect(keyPressEvent); + } catch (e) { + // empty + } + chatBar.close(); + chatHistory.close(); +} \ No newline at end of file diff --git a/scripts/communityModules/chat/FloofChat.qml b/scripts/communityModules/chat/FloofChat.qml new file mode 100644 index 0000000000..8d96bf7e42 --- /dev/null +++ b/scripts/communityModules/chat/FloofChat.qml @@ -0,0 +1,157 @@ +import QtQuick 2.5 +import QtQuick.Controls 1.4 +//import Hifi 1.0 as Hifi + +Rectangle { + id: root + property var window + + Binding { target: root; property:'window'; value: parent.parent; when: Boolean(parent.parent) } + + Binding { target: window; property: 'shown'; value: false; when: Boolean(window) } + Component.onDestruction: thing && thing.destroy() + + property var hist : -1; + property var history : []; + + signal sendToScript(var message); + color: "#00000000" + property alias thing: thing + + function sendMessage(text){ + sendToScript(text); + } + + function fromScript(message) { + console.log("fromScript "+message); + var data = {failed:true}; + try{ + data = JSON.parse(message); + } catch(e){ + // + } + if (!data.failed) { + if (data.cmd) { + JSConsole.executeCommand(data.msg); + } + console.log(data.visible); + if (data.visible) { + thing.visible = true; + textArea.focus = true; + } else if (!data.visible) { + thing.visible = false; + textArea.focus = false; + } + if (data.history) { + history = data.history; + } + } + } + + Rectangle { + id: thing + parent: desktop + x: 0 + y: parent.height - height + width: parent.width + height: 64 + color: "#00000000" + z: 99 + visible:true + + TextArea { + id: textArea + x: 64 + width: parent.width-64 + height: parent.height + text:"" + textColor: "#000000" + clip: false + font.pointSize: 20 + + function _onEnterPressed(event) { + sendMessage(JSON.stringify({type:"MSG", message:text, event:event})); + history.unshift(text); + text = ""; + hist = -1; + } + + function upPressed(event) { + hist++; + if (hist > history.length-1) { + hist = history.length-1; + } + text = history[hist]; + } + function downPressed(event) { + hist--; + if (hist < -1) { + hist = -1; + } + if (hist === -1) { + text = ""; + } else{ + text = history[hist]; + } + } + + Keys.onReturnPressed: { _onEnterPressed(event); } + Keys.onEnterPressed: { _onEnterPressed(event); } + Keys.onUpPressed: { upPressed(event); } + Keys.onDownPressed: { downPressed(event); } + } + + MouseArea { + anchors.rightMargin: -1 + anchors.bottomMargin: 0 + anchors.topMargin: 0 + anchors.leftMargin: 63 + anchors.fill: parent + propagateComposedEvents: false + acceptedButtons: Qt.AllButtons + enabled: false + onPressed: { + thing.forceActiveFocus(); + mouse.accepted = true; + } + } + + Button { + id: button + x: 0 + y: 0 + width: 64 + height: 64 + text: qsTr("Button") + clip: false + opacity: 1 + iconSource: "" + visible: true + + Image { + id: image + x: 0 + y: 0 + width: 64 + height: 64 + visible: true + fillMode: Image.PreserveAspectFit + source: "chat.png" + } + } + + } + + Connections { + target: button + onClicked: + sendMessage(JSON.stringify({type:"CMD",cmd:"Clicked"})); + } + +} + + +/*##^## Designer { + D{i:0;autoSize:true;height:480;width:640} +} + ##^##*/ diff --git a/scripts/communityModules/chat/chat.png b/scripts/communityModules/chat/chat.png new file mode 100644 index 0000000000..995b67a5cb Binary files /dev/null and b/scripts/communityModules/chat/chat.png differ diff --git a/scripts/communityModules/chat/css/FloofChat.css b/scripts/communityModules/chat/css/FloofChat.css new file mode 100644 index 0000000000..476712ffbb --- /dev/null +++ b/scripts/communityModules/chat/css/FloofChat.css @@ -0,0 +1,157 @@ + +.disabledrag { + -webkit-user-drag: none !important; + -khtml-user-drag: none !important; + -moz-user-drag: none !important; + -o-user-drag: none !important; + user-drag: none !important; +} + +html { + height: 100%; +} + +div.dockButton { + + position: absolute; /*or fixed*/ + right: 10px; + + + overflow: hidden; + border: 1px solid #ccc; + background-color: #f1f1f1; +} + +div.dockButton button { + background-color: inherit; + float: right; + border: none; + outline: none; + cursor: pointer; + padding: 14px 16px; + transition: 0.3s; +} + +/* Change background color of buttons on hover */ +div.dockButton button:hover { + background-color: #ddd; +} + +/* Create an active/current tablink class */ +div.dockButton button.active { + background-color: #ccc; +} + +/* Style the tab content */ +.TabContent { + display: none; + + padding: 6px 12px; + border-top: none; +} + +body { + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: hidden; + margin: 0; + font-family: 'Raleway', sans-serif; + color: white; + background: linear-gradient(#2b2b2b, #0f212e); +} + +.Content { + min-height: 100vh; + font-size: 20px; + width: 100%; + height: 100%; +} + +.ChatLog { + height: calc(100vh - 137px); + padding: 20px !important; + font-size: 20px; + color: white; + background-color: black; + overflow-x: hidden; + overflow-y: scroll; + word-wrap: break-word; +} + +.ChatLogLine { + margin-bottom: 15px; +} + +.ChatLogLineDisplayName { + font-weight: bold; +} + +.ChatLogLineMessage { +} + +.LogLogLine { + margin-bottom: 15px; + padding: 10px !important; +} + +.LogLogLineMessage { + /*font-style: italic;*/ +} + +.ChatInput { + color: #252525; + background: #252525; + height: 60px !important; +} + +.ChatInputText { + padding: 5px !important; + height: 50px !important; + width: calc(100vw - 20px) !important; + font-size: 20px !important; + background-color: white !important; + border-style: solid !important; + border-color: #232323 !important; + border-width: 5px 5px 5px 5px !important; + +} + +.responsive { + width: 100%; + max-width: 420px; + height: auto; +} + +.row .col { + padding: 0; +} + +.switch label .lever { + content: ""; + display: inline-block; + position: relative; + width: 36px; + height: 14px; + background-color: rgba(0, 0, 0, 0.38); + border-radius: 15px; + margin-right: 10px; + -webkit-transition: background 0.3s ease; + transition: background 0.3s ease; + vertical-align: middle; + margin: 0 16px; +} + +.muteSwitch label input[type=checkbox]:checked + .lever:after { + background-color: #a62113 !important; +} + +img, a{ + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-user-drag: none; + user-drag: none; + -webkit-touch-callout: none; +} \ No newline at end of file diff --git a/scripts/communityModules/chat/css/materialize.css b/scripts/communityModules/chat/css/materialize.css new file mode 100644 index 0000000000..a67c8214c0 --- /dev/null +++ b/scripts/communityModules/chat/css/materialize.css @@ -0,0 +1,9086 @@ +/*! + * Materialize v1.0.0 (http://materializecss.com) + * Copyright 2014-2017 Materialize + * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) + */ +.materialize-red { + background-color: #e51c23 !important; +} + +.materialize-red-text { + color: #e51c23 !important; +} + +.materialize-red.lighten-5 { + background-color: #fdeaeb !important; +} + +.materialize-red-text.text-lighten-5 { + color: #fdeaeb !important; +} + +.materialize-red.lighten-4 { + background-color: #f8c1c3 !important; +} + +.materialize-red-text.text-lighten-4 { + color: #f8c1c3 !important; +} + +.materialize-red.lighten-3 { + background-color: #f3989b !important; +} + +.materialize-red-text.text-lighten-3 { + color: #f3989b !important; +} + +.materialize-red.lighten-2 { + background-color: #ee6e73 !important; +} + +.materialize-red-text.text-lighten-2 { + color: #ee6e73 !important; +} + +.materialize-red.lighten-1 { + background-color: #ea454b !important; +} + +.materialize-red-text.text-lighten-1 { + color: #ea454b !important; +} + +.materialize-red.darken-1 { + background-color: #d0181e !important; +} + +.materialize-red-text.text-darken-1 { + color: #d0181e !important; +} + +.materialize-red.darken-2 { + background-color: #b9151b !important; +} + +.materialize-red-text.text-darken-2 { + color: #b9151b !important; +} + +.materialize-red.darken-3 { + background-color: #a21318 !important; +} + +.materialize-red-text.text-darken-3 { + color: #a21318 !important; +} + +.materialize-red.darken-4 { + background-color: #8b1014 !important; +} + +.materialize-red-text.text-darken-4 { + color: #8b1014 !important; +} + +.red { + background-color: #F44336 !important; +} + +.red-text { + color: #F44336 !important; +} + +.red.lighten-5 { + background-color: #FFEBEE !important; +} + +.red-text.text-lighten-5 { + color: #FFEBEE !important; +} + +.red.lighten-4 { + background-color: #FFCDD2 !important; +} + +.red-text.text-lighten-4 { + color: #FFCDD2 !important; +} + +.red.lighten-3 { + background-color: #EF9A9A !important; +} + +.red-text.text-lighten-3 { + color: #EF9A9A !important; +} + +.red.lighten-2 { + background-color: #E57373 !important; +} + +.red-text.text-lighten-2 { + color: #E57373 !important; +} + +.red.lighten-1 { + background-color: #EF5350 !important; +} + +.red-text.text-lighten-1 { + color: #EF5350 !important; +} + +.red.darken-1 { + background-color: #E53935 !important; +} + +.red-text.text-darken-1 { + color: #E53935 !important; +} + +.red.darken-2 { + background-color: #D32F2F !important; +} + +.red-text.text-darken-2 { + color: #D32F2F !important; +} + +.red.darken-3 { + background-color: #C62828 !important; +} + +.red-text.text-darken-3 { + color: #C62828 !important; +} + +.red.darken-4 { + background-color: #B71C1C !important; +} + +.red-text.text-darken-4 { + color: #B71C1C !important; +} + +.red.accent-1 { + background-color: #FF8A80 !important; +} + +.red-text.text-accent-1 { + color: #FF8A80 !important; +} + +.red.accent-2 { + background-color: #FF5252 !important; +} + +.red-text.text-accent-2 { + color: #FF5252 !important; +} + +.red.accent-3 { + background-color: #FF1744 !important; +} + +.red-text.text-accent-3 { + color: #FF1744 !important; +} + +.red.accent-4 { + background-color: #D50000 !important; +} + +.red-text.text-accent-4 { + color: #D50000 !important; +} + +.pink { + background-color: #e91e63 !important; +} + +.pink-text { + color: #e91e63 !important; +} + +.pink.lighten-5 { + background-color: #fce4ec !important; +} + +.pink-text.text-lighten-5 { + color: #fce4ec !important; +} + +.pink.lighten-4 { + background-color: #f8bbd0 !important; +} + +.pink-text.text-lighten-4 { + color: #f8bbd0 !important; +} + +.pink.lighten-3 { + background-color: #f48fb1 !important; +} + +.pink-text.text-lighten-3 { + color: #f48fb1 !important; +} + +.pink.lighten-2 { + background-color: #f06292 !important; +} + +.pink-text.text-lighten-2 { + color: #f06292 !important; +} + +.pink.lighten-1 { + background-color: #ec407a !important; +} + +.pink-text.text-lighten-1 { + color: #ec407a !important; +} + +.pink.darken-1 { + background-color: #d81b60 !important; +} + +.pink-text.text-darken-1 { + color: #d81b60 !important; +} + +.pink.darken-2 { + background-color: #c2185b !important; +} + +.pink-text.text-darken-2 { + color: #c2185b !important; +} + +.pink.darken-3 { + background-color: #ad1457 !important; +} + +.pink-text.text-darken-3 { + color: #ad1457 !important; +} + +.pink.darken-4 { + background-color: #880e4f !important; +} + +.pink-text.text-darken-4 { + color: #880e4f !important; +} + +.pink.accent-1 { + background-color: #ff80ab !important; +} + +.pink-text.text-accent-1 { + color: #ff80ab !important; +} + +.pink.accent-2 { + background-color: #ff4081 !important; +} + +.pink-text.text-accent-2 { + color: #ff4081 !important; +} + +.pink.accent-3 { + background-color: #f50057 !important; +} + +.pink-text.text-accent-3 { + color: #f50057 !important; +} + +.pink.accent-4 { + background-color: #c51162 !important; +} + +.pink-text.text-accent-4 { + color: #c51162 !important; +} + +.purple { + background-color: #9c27b0 !important; +} + +.purple-text { + color: #9c27b0 !important; +} + +.purple.lighten-5 { + background-color: #f3e5f5 !important; +} + +.purple-text.text-lighten-5 { + color: #f3e5f5 !important; +} + +.purple.lighten-4 { + background-color: #e1bee7 !important; +} + +.purple-text.text-lighten-4 { + color: #e1bee7 !important; +} + +.purple.lighten-3 { + background-color: #ce93d8 !important; +} + +.purple-text.text-lighten-3 { + color: #ce93d8 !important; +} + +.purple.lighten-2 { + background-color: #ba68c8 !important; +} + +.purple-text.text-lighten-2 { + color: #ba68c8 !important; +} + +.purple.lighten-1 { + background-color: #ab47bc !important; +} + +.purple-text.text-lighten-1 { + color: #ab47bc !important; +} + +.purple.darken-1 { + background-color: #8e24aa !important; +} + +.purple-text.text-darken-1 { + color: #8e24aa !important; +} + +.purple.darken-2 { + background-color: #7b1fa2 !important; +} + +.purple-text.text-darken-2 { + color: #7b1fa2 !important; +} + +.purple.darken-3 { + background-color: #6a1b9a !important; +} + +.purple-text.text-darken-3 { + color: #6a1b9a !important; +} + +.purple.darken-4 { + background-color: #4a148c !important; +} + +.purple-text.text-darken-4 { + color: #4a148c !important; +} + +.purple.accent-1 { + background-color: #ea80fc !important; +} + +.purple-text.text-accent-1 { + color: #ea80fc !important; +} + +.purple.accent-2 { + background-color: #e040fb !important; +} + +.purple-text.text-accent-2 { + color: #e040fb !important; +} + +.purple.accent-3 { + background-color: #d500f9 !important; +} + +.purple-text.text-accent-3 { + color: #d500f9 !important; +} + +.purple.accent-4 { + background-color: #aa00ff !important; +} + +.purple-text.text-accent-4 { + color: #aa00ff !important; +} + +.deep-purple { + background-color: #673ab7 !important; +} + +.deep-purple-text { + color: #673ab7 !important; +} + +.deep-purple.lighten-5 { + background-color: #ede7f6 !important; +} + +.deep-purple-text.text-lighten-5 { + color: #ede7f6 !important; +} + +.deep-purple.lighten-4 { + background-color: #d1c4e9 !important; +} + +.deep-purple-text.text-lighten-4 { + color: #d1c4e9 !important; +} + +.deep-purple.lighten-3 { + background-color: #b39ddb !important; +} + +.deep-purple-text.text-lighten-3 { + color: #b39ddb !important; +} + +.deep-purple.lighten-2 { + background-color: #9575cd !important; +} + +.deep-purple-text.text-lighten-2 { + color: #9575cd !important; +} + +.deep-purple.lighten-1 { + background-color: #7e57c2 !important; +} + +.deep-purple-text.text-lighten-1 { + color: #7e57c2 !important; +} + +.deep-purple.darken-1 { + background-color: #5e35b1 !important; +} + +.deep-purple-text.text-darken-1 { + color: #5e35b1 !important; +} + +.deep-purple.darken-2 { + background-color: #512da8 !important; +} + +.deep-purple-text.text-darken-2 { + color: #512da8 !important; +} + +.deep-purple.darken-3 { + background-color: #4527a0 !important; +} + +.deep-purple-text.text-darken-3 { + color: #4527a0 !important; +} + +.deep-purple.darken-4 { + background-color: #311b92 !important; +} + +.deep-purple-text.text-darken-4 { + color: #311b92 !important; +} + +.deep-purple.accent-1 { + background-color: #b388ff !important; +} + +.deep-purple-text.text-accent-1 { + color: #b388ff !important; +} + +.deep-purple.accent-2 { + background-color: #7c4dff !important; +} + +.deep-purple-text.text-accent-2 { + color: #7c4dff !important; +} + +.deep-purple.accent-3 { + background-color: #651fff !important; +} + +.deep-purple-text.text-accent-3 { + color: #651fff !important; +} + +.deep-purple.accent-4 { + background-color: #6200ea !important; +} + +.deep-purple-text.text-accent-4 { + color: #6200ea !important; +} + +.indigo { + background-color: #3f51b5 !important; +} + +.indigo-text { + color: #3f51b5 !important; +} + +.indigo.lighten-5 { + background-color: #e8eaf6 !important; +} + +.indigo-text.text-lighten-5 { + color: #e8eaf6 !important; +} + +.indigo.lighten-4 { + background-color: #c5cae9 !important; +} + +.indigo-text.text-lighten-4 { + color: #c5cae9 !important; +} + +.indigo.lighten-3 { + background-color: #9fa8da !important; +} + +.indigo-text.text-lighten-3 { + color: #9fa8da !important; +} + +.indigo.lighten-2 { + background-color: #7986cb !important; +} + +.indigo-text.text-lighten-2 { + color: #7986cb !important; +} + +.indigo.lighten-1 { + background-color: #5c6bc0 !important; +} + +.indigo-text.text-lighten-1 { + color: #5c6bc0 !important; +} + +.indigo.darken-1 { + background-color: #3949ab !important; +} + +.indigo-text.text-darken-1 { + color: #3949ab !important; +} + +.indigo.darken-2 { + background-color: #303f9f !important; +} + +.indigo-text.text-darken-2 { + color: #303f9f !important; +} + +.indigo.darken-3 { + background-color: #283593 !important; +} + +.indigo-text.text-darken-3 { + color: #283593 !important; +} + +.indigo.darken-4 { + background-color: #1a237e !important; +} + +.indigo-text.text-darken-4 { + color: #1a237e !important; +} + +.indigo.accent-1 { + background-color: #8c9eff !important; +} + +.indigo-text.text-accent-1 { + color: #8c9eff !important; +} + +.indigo.accent-2 { + background-color: #536dfe !important; +} + +.indigo-text.text-accent-2 { + color: #536dfe !important; +} + +.indigo.accent-3 { + background-color: #3d5afe !important; +} + +.indigo-text.text-accent-3 { + color: #3d5afe !important; +} + +.indigo.accent-4 { + background-color: #304ffe !important; +} + +.indigo-text.text-accent-4 { + color: #304ffe !important; +} + +.blue { + background-color: #2196F3 !important; +} + +.blue-text { + color: #2196F3 !important; +} + +.blue.lighten-5 { + background-color: #E3F2FD !important; +} + +.blue-text.text-lighten-5 { + color: #E3F2FD !important; +} + +.blue.lighten-4 { + background-color: #BBDEFB !important; +} + +.blue-text.text-lighten-4 { + color: #BBDEFB !important; +} + +.blue.lighten-3 { + background-color: #90CAF9 !important; +} + +.blue-text.text-lighten-3 { + color: #90CAF9 !important; +} + +.blue.lighten-2 { + background-color: #64B5F6 !important; +} + +.blue-text.text-lighten-2 { + color: #64B5F6 !important; +} + +.blue.lighten-1 { + background-color: #42A5F5 !important; +} + +.blue-text.text-lighten-1 { + color: #42A5F5 !important; +} + +.blue.darken-1 { + background-color: #1E88E5 !important; +} + +.blue-text.text-darken-1 { + color: #1E88E5 !important; +} + +.blue.darken-2 { + background-color: #1976D2 !important; +} + +.blue-text.text-darken-2 { + color: #1976D2 !important; +} + +.blue.darken-3 { + background-color: #1565C0 !important; +} + +.blue-text.text-darken-3 { + color: #1565C0 !important; +} + +.blue.darken-4 { + background-color: #0D47A1 !important; +} + +.blue-text.text-darken-4 { + color: #0D47A1 !important; +} + +.blue.accent-1 { + background-color: #82B1FF !important; +} + +.blue-text.text-accent-1 { + color: #82B1FF !important; +} + +.blue.accent-2 { + background-color: #448AFF !important; +} + +.blue-text.text-accent-2 { + color: #448AFF !important; +} + +.blue.accent-3 { + background-color: #2979FF !important; +} + +.blue-text.text-accent-3 { + color: #2979FF !important; +} + +.blue.accent-4 { + background-color: #2962FF !important; +} + +.blue-text.text-accent-4 { + color: #2962FF !important; +} + +.light-blue { + background-color: #03a9f4 !important; +} + +.light-blue-text { + color: #03a9f4 !important; +} + +.light-blue.lighten-5 { + background-color: #e1f5fe !important; +} + +.light-blue-text.text-lighten-5 { + color: #e1f5fe !important; +} + +.light-blue.lighten-4 { + background-color: #b3e5fc !important; +} + +.light-blue-text.text-lighten-4 { + color: #b3e5fc !important; +} + +.light-blue.lighten-3 { + background-color: #81d4fa !important; +} + +.light-blue-text.text-lighten-3 { + color: #81d4fa !important; +} + +.light-blue.lighten-2 { + background-color: #4fc3f7 !important; +} + +.light-blue-text.text-lighten-2 { + color: #4fc3f7 !important; +} + +.light-blue.lighten-1 { + background-color: #29b6f6 !important; +} + +.light-blue-text.text-lighten-1 { + color: #29b6f6 !important; +} + +.light-blue.darken-1 { + background-color: #039be5 !important; +} + +.light-blue-text.text-darken-1 { + color: #039be5 !important; +} + +.light-blue.darken-2 { + background-color: #0288d1 !important; +} + +.light-blue-text.text-darken-2 { + color: #0288d1 !important; +} + +.light-blue.darken-3 { + background-color: #0277bd !important; +} + +.light-blue-text.text-darken-3 { + color: #0277bd !important; +} + +.light-blue.darken-4 { + background-color: #01579b !important; +} + +.light-blue-text.text-darken-4 { + color: #01579b !important; +} + +.light-blue.accent-1 { + background-color: #80d8ff !important; +} + +.light-blue-text.text-accent-1 { + color: #80d8ff !important; +} + +.light-blue.accent-2 { + background-color: #40c4ff !important; +} + +.light-blue-text.text-accent-2 { + color: #40c4ff !important; +} + +.light-blue.accent-3 { + background-color: #00b0ff !important; +} + +.light-blue-text.text-accent-3 { + color: #00b0ff !important; +} + +.light-blue.accent-4 { + background-color: #0091ea !important; +} + +.light-blue-text.text-accent-4 { + color: #0091ea !important; +} + +.cyan { + background-color: #00bcd4 !important; +} + +.cyan-text { + color: #00bcd4 !important; +} + +.cyan.lighten-5 { + background-color: #e0f7fa !important; +} + +.cyan-text.text-lighten-5 { + color: #e0f7fa !important; +} + +.cyan.lighten-4 { + background-color: #b2ebf2 !important; +} + +.cyan-text.text-lighten-4 { + color: #b2ebf2 !important; +} + +.cyan.lighten-3 { + background-color: #80deea !important; +} + +.cyan-text.text-lighten-3 { + color: #80deea !important; +} + +.cyan.lighten-2 { + background-color: #4dd0e1 !important; +} + +.cyan-text.text-lighten-2 { + color: #4dd0e1 !important; +} + +.cyan.lighten-1 { + background-color: #26c6da !important; +} + +.cyan-text.text-lighten-1 { + color: #26c6da !important; +} + +.cyan.darken-1 { + background-color: #00acc1 !important; +} + +.cyan-text.text-darken-1 { + color: #00acc1 !important; +} + +.cyan.darken-2 { + background-color: #0097a7 !important; +} + +.cyan-text.text-darken-2 { + color: #0097a7 !important; +} + +.cyan.darken-3 { + background-color: #00838f !important; +} + +.cyan-text.text-darken-3 { + color: #00838f !important; +} + +.cyan.darken-4 { + background-color: #006064 !important; +} + +.cyan-text.text-darken-4 { + color: #006064 !important; +} + +.cyan.accent-1 { + background-color: #84ffff !important; +} + +.cyan-text.text-accent-1 { + color: #84ffff !important; +} + +.cyan.accent-2 { + background-color: #18ffff !important; +} + +.cyan-text.text-accent-2 { + color: #18ffff !important; +} + +.cyan.accent-3 { + background-color: #00e5ff !important; +} + +.cyan-text.text-accent-3 { + color: #00e5ff !important; +} + +.cyan.accent-4 { + background-color: #00b8d4 !important; +} + +.cyan-text.text-accent-4 { + color: #00b8d4 !important; +} + +.teal { + background-color: #009688 !important; +} + +.teal-text { + color: #009688 !important; +} + +.teal.lighten-5 { + background-color: #e0f2f1 !important; +} + +.teal-text.text-lighten-5 { + color: #e0f2f1 !important; +} + +.teal.lighten-4 { + background-color: #b2dfdb !important; +} + +.teal-text.text-lighten-4 { + color: #b2dfdb !important; +} + +.teal.lighten-3 { + background-color: #80cbc4 !important; +} + +.teal-text.text-lighten-3 { + color: #80cbc4 !important; +} + +.teal.lighten-2 { + background-color: #4db6ac !important; +} + +.teal-text.text-lighten-2 { + color: #4db6ac !important; +} + +.teal.lighten-1 { + background-color: #26a69a !important; +} + +.teal-text.text-lighten-1 { + color: #26a69a !important; +} + +.teal.darken-1 { + background-color: #00897b !important; +} + +.teal-text.text-darken-1 { + color: #00897b !important; +} + +.teal.darken-2 { + background-color: #00796b !important; +} + +.teal-text.text-darken-2 { + color: #00796b !important; +} + +.teal.darken-3 { + background-color: #00695c !important; +} + +.teal-text.text-darken-3 { + color: #00695c !important; +} + +.teal.darken-4 { + background-color: #004d40 !important; +} + +.teal-text.text-darken-4 { + color: #004d40 !important; +} + +.teal.accent-1 { + background-color: #a7ffeb !important; +} + +.teal-text.text-accent-1 { + color: #a7ffeb !important; +} + +.teal.accent-2 { + background-color: #64ffda !important; +} + +.teal-text.text-accent-2 { + color: #64ffda !important; +} + +.teal.accent-3 { + background-color: #1de9b6 !important; +} + +.teal-text.text-accent-3 { + color: #1de9b6 !important; +} + +.teal.accent-4 { + background-color: #00bfa5 !important; +} + +.teal-text.text-accent-4 { + color: #00bfa5 !important; +} + +.green { + background-color: #4CAF50 !important; +} + +.green-text { + color: #4CAF50 !important; +} + +.green.lighten-5 { + background-color: #E8F5E9 !important; +} + +.green-text.text-lighten-5 { + color: #E8F5E9 !important; +} + +.green.lighten-4 { + background-color: #C8E6C9 !important; +} + +.green-text.text-lighten-4 { + color: #C8E6C9 !important; +} + +.green.lighten-3 { + background-color: #A5D6A7 !important; +} + +.green-text.text-lighten-3 { + color: #A5D6A7 !important; +} + +.green.lighten-2 { + background-color: #81C784 !important; +} + +.green-text.text-lighten-2 { + color: #81C784 !important; +} + +.green.lighten-1 { + background-color: #66BB6A !important; +} + +.green-text.text-lighten-1 { + color: #66BB6A !important; +} + +.green.darken-1 { + background-color: #43A047 !important; +} + +.green-text.text-darken-1 { + color: #43A047 !important; +} + +.green.darken-2 { + background-color: #388E3C !important; +} + +.green-text.text-darken-2 { + color: #388E3C !important; +} + +.green.darken-3 { + background-color: #2E7D32 !important; +} + +.green-text.text-darken-3 { + color: #2E7D32 !important; +} + +.green.darken-4 { + background-color: #1B5E20 !important; +} + +.green-text.text-darken-4 { + color: #1B5E20 !important; +} + +.green.accent-1 { + background-color: #B9F6CA !important; +} + +.green-text.text-accent-1 { + color: #B9F6CA !important; +} + +.green.accent-2 { + background-color: #69F0AE !important; +} + +.green-text.text-accent-2 { + color: #69F0AE !important; +} + +.green.accent-3 { + background-color: #00E676 !important; +} + +.green-text.text-accent-3 { + color: #00E676 !important; +} + +.green.accent-4 { + background-color: #00C853 !important; +} + +.green-text.text-accent-4 { + color: #00C853 !important; +} + +.light-green { + background-color: #8bc34a !important; +} + +.light-green-text { + color: #8bc34a !important; +} + +.light-green.lighten-5 { + background-color: #f1f8e9 !important; +} + +.light-green-text.text-lighten-5 { + color: #f1f8e9 !important; +} + +.light-green.lighten-4 { + background-color: #dcedc8 !important; +} + +.light-green-text.text-lighten-4 { + color: #dcedc8 !important; +} + +.light-green.lighten-3 { + background-color: #c5e1a5 !important; +} + +.light-green-text.text-lighten-3 { + color: #c5e1a5 !important; +} + +.light-green.lighten-2 { + background-color: #aed581 !important; +} + +.light-green-text.text-lighten-2 { + color: #aed581 !important; +} + +.light-green.lighten-1 { + background-color: #9ccc65 !important; +} + +.light-green-text.text-lighten-1 { + color: #9ccc65 !important; +} + +.light-green.darken-1 { + background-color: #7cb342 !important; +} + +.light-green-text.text-darken-1 { + color: #7cb342 !important; +} + +.light-green.darken-2 { + background-color: #689f38 !important; +} + +.light-green-text.text-darken-2 { + color: #689f38 !important; +} + +.light-green.darken-3 { + background-color: #558b2f !important; +} + +.light-green-text.text-darken-3 { + color: #558b2f !important; +} + +.light-green.darken-4 { + background-color: #33691e !important; +} + +.light-green-text.text-darken-4 { + color: #33691e !important; +} + +.light-green.accent-1 { + background-color: #ccff90 !important; +} + +.light-green-text.text-accent-1 { + color: #ccff90 !important; +} + +.light-green.accent-2 { + background-color: #b2ff59 !important; +} + +.light-green-text.text-accent-2 { + color: #b2ff59 !important; +} + +.light-green.accent-3 { + background-color: #76ff03 !important; +} + +.light-green-text.text-accent-3 { + color: #76ff03 !important; +} + +.light-green.accent-4 { + background-color: #64dd17 !important; +} + +.light-green-text.text-accent-4 { + color: #64dd17 !important; +} + +.lime { + background-color: #cddc39 !important; +} + +.lime-text { + color: #cddc39 !important; +} + +.lime.lighten-5 { + background-color: #f9fbe7 !important; +} + +.lime-text.text-lighten-5 { + color: #f9fbe7 !important; +} + +.lime.lighten-4 { + background-color: #f0f4c3 !important; +} + +.lime-text.text-lighten-4 { + color: #f0f4c3 !important; +} + +.lime.lighten-3 { + background-color: #e6ee9c !important; +} + +.lime-text.text-lighten-3 { + color: #e6ee9c !important; +} + +.lime.lighten-2 { + background-color: #dce775 !important; +} + +.lime-text.text-lighten-2 { + color: #dce775 !important; +} + +.lime.lighten-1 { + background-color: #d4e157 !important; +} + +.lime-text.text-lighten-1 { + color: #d4e157 !important; +} + +.lime.darken-1 { + background-color: #c0ca33 !important; +} + +.lime-text.text-darken-1 { + color: #c0ca33 !important; +} + +.lime.darken-2 { + background-color: #afb42b !important; +} + +.lime-text.text-darken-2 { + color: #afb42b !important; +} + +.lime.darken-3 { + background-color: #9e9d24 !important; +} + +.lime-text.text-darken-3 { + color: #9e9d24 !important; +} + +.lime.darken-4 { + background-color: #827717 !important; +} + +.lime-text.text-darken-4 { + color: #827717 !important; +} + +.lime.accent-1 { + background-color: #f4ff81 !important; +} + +.lime-text.text-accent-1 { + color: #f4ff81 !important; +} + +.lime.accent-2 { + background-color: #eeff41 !important; +} + +.lime-text.text-accent-2 { + color: #eeff41 !important; +} + +.lime.accent-3 { + background-color: #c6ff00 !important; +} + +.lime-text.text-accent-3 { + color: #c6ff00 !important; +} + +.lime.accent-4 { + background-color: #aeea00 !important; +} + +.lime-text.text-accent-4 { + color: #aeea00 !important; +} + +.yellow { + background-color: #ffeb3b !important; +} + +.yellow-text { + color: #ffeb3b !important; +} + +.yellow.lighten-5 { + background-color: #fffde7 !important; +} + +.yellow-text.text-lighten-5 { + color: #fffde7 !important; +} + +.yellow.lighten-4 { + background-color: #fff9c4 !important; +} + +.yellow-text.text-lighten-4 { + color: #fff9c4 !important; +} + +.yellow.lighten-3 { + background-color: #fff59d !important; +} + +.yellow-text.text-lighten-3 { + color: #fff59d !important; +} + +.yellow.lighten-2 { + background-color: #fff176 !important; +} + +.yellow-text.text-lighten-2 { + color: #fff176 !important; +} + +.yellow.lighten-1 { + background-color: #ffee58 !important; +} + +.yellow-text.text-lighten-1 { + color: #ffee58 !important; +} + +.yellow.darken-1 { + background-color: #fdd835 !important; +} + +.yellow-text.text-darken-1 { + color: #fdd835 !important; +} + +.yellow.darken-2 { + background-color: #fbc02d !important; +} + +.yellow-text.text-darken-2 { + color: #fbc02d !important; +} + +.yellow.darken-3 { + background-color: #f9a825 !important; +} + +.yellow-text.text-darken-3 { + color: #f9a825 !important; +} + +.yellow.darken-4 { + background-color: #f57f17 !important; +} + +.yellow-text.text-darken-4 { + color: #f57f17 !important; +} + +.yellow.accent-1 { + background-color: #ffff8d !important; +} + +.yellow-text.text-accent-1 { + color: #ffff8d !important; +} + +.yellow.accent-2 { + background-color: #ffff00 !important; +} + +.yellow-text.text-accent-2 { + color: #ffff00 !important; +} + +.yellow.accent-3 { + background-color: #ffea00 !important; +} + +.yellow-text.text-accent-3 { + color: #ffea00 !important; +} + +.yellow.accent-4 { + background-color: #ffd600 !important; +} + +.yellow-text.text-accent-4 { + color: #ffd600 !important; +} + +.amber { + background-color: #ffc107 !important; +} + +.amber-text { + color: #ffc107 !important; +} + +.amber.lighten-5 { + background-color: #fff8e1 !important; +} + +.amber-text.text-lighten-5 { + color: #fff8e1 !important; +} + +.amber.lighten-4 { + background-color: #ffecb3 !important; +} + +.amber-text.text-lighten-4 { + color: #ffecb3 !important; +} + +.amber.lighten-3 { + background-color: #ffe082 !important; +} + +.amber-text.text-lighten-3 { + color: #ffe082 !important; +} + +.amber.lighten-2 { + background-color: #ffd54f !important; +} + +.amber-text.text-lighten-2 { + color: #ffd54f !important; +} + +.amber.lighten-1 { + background-color: #ffca28 !important; +} + +.amber-text.text-lighten-1 { + color: #ffca28 !important; +} + +.amber.darken-1 { + background-color: #ffb300 !important; +} + +.amber-text.text-darken-1 { + color: #ffb300 !important; +} + +.amber.darken-2 { + background-color: #ffa000 !important; +} + +.amber-text.text-darken-2 { + color: #ffa000 !important; +} + +.amber.darken-3 { + background-color: #ff8f00 !important; +} + +.amber-text.text-darken-3 { + color: #ff8f00 !important; +} + +.amber.darken-4 { + background-color: #ff6f00 !important; +} + +.amber-text.text-darken-4 { + color: #ff6f00 !important; +} + +.amber.accent-1 { + background-color: #ffe57f !important; +} + +.amber-text.text-accent-1 { + color: #ffe57f !important; +} + +.amber.accent-2 { + background-color: #ffd740 !important; +} + +.amber-text.text-accent-2 { + color: #ffd740 !important; +} + +.amber.accent-3 { + background-color: #ffc400 !important; +} + +.amber-text.text-accent-3 { + color: #ffc400 !important; +} + +.amber.accent-4 { + background-color: #ffab00 !important; +} + +.amber-text.text-accent-4 { + color: #ffab00 !important; +} + +.orange { + background-color: #ff9800 !important; +} + +.orange-text { + color: #ff9800 !important; +} + +.orange.lighten-5 { + background-color: #fff3e0 !important; +} + +.orange-text.text-lighten-5 { + color: #fff3e0 !important; +} + +.orange.lighten-4 { + background-color: #ffe0b2 !important; +} + +.orange-text.text-lighten-4 { + color: #ffe0b2 !important; +} + +.orange.lighten-3 { + background-color: #ffcc80 !important; +} + +.orange-text.text-lighten-3 { + color: #ffcc80 !important; +} + +.orange.lighten-2 { + background-color: #ffb74d !important; +} + +.orange-text.text-lighten-2 { + color: #ffb74d !important; +} + +.orange.lighten-1 { + background-color: #ffa726 !important; +} + +.orange-text.text-lighten-1 { + color: #ffa726 !important; +} + +.orange.darken-1 { + background-color: #fb8c00 !important; +} + +.orange-text.text-darken-1 { + color: #fb8c00 !important; +} + +.orange.darken-2 { + background-color: #f57c00 !important; +} + +.orange-text.text-darken-2 { + color: #f57c00 !important; +} + +.orange.darken-3 { + background-color: #ef6c00 !important; +} + +.orange-text.text-darken-3 { + color: #ef6c00 !important; +} + +.orange.darken-4 { + background-color: #e65100 !important; +} + +.orange-text.text-darken-4 { + color: #e65100 !important; +} + +.orange.accent-1 { + background-color: #ffd180 !important; +} + +.orange-text.text-accent-1 { + color: #ffd180 !important; +} + +.orange.accent-2 { + background-color: #ffab40 !important; +} + +.orange-text.text-accent-2 { + color: #ffab40 !important; +} + +.orange.accent-3 { + background-color: #ff9100 !important; +} + +.orange-text.text-accent-3 { + color: #ff9100 !important; +} + +.orange.accent-4 { + background-color: #ff6d00 !important; +} + +.orange-text.text-accent-4 { + color: #ff6d00 !important; +} + +.deep-orange { + background-color: #ff5722 !important; +} + +.deep-orange-text { + color: #ff5722 !important; +} + +.deep-orange.lighten-5 { + background-color: #fbe9e7 !important; +} + +.deep-orange-text.text-lighten-5 { + color: #fbe9e7 !important; +} + +.deep-orange.lighten-4 { + background-color: #ffccbc !important; +} + +.deep-orange-text.text-lighten-4 { + color: #ffccbc !important; +} + +.deep-orange.lighten-3 { + background-color: #ffab91 !important; +} + +.deep-orange-text.text-lighten-3 { + color: #ffab91 !important; +} + +.deep-orange.lighten-2 { + background-color: #ff8a65 !important; +} + +.deep-orange-text.text-lighten-2 { + color: #ff8a65 !important; +} + +.deep-orange.lighten-1 { + background-color: #ff7043 !important; +} + +.deep-orange-text.text-lighten-1 { + color: #ff7043 !important; +} + +.deep-orange.darken-1 { + background-color: #f4511e !important; +} + +.deep-orange-text.text-darken-1 { + color: #f4511e !important; +} + +.deep-orange.darken-2 { + background-color: #e64a19 !important; +} + +.deep-orange-text.text-darken-2 { + color: #e64a19 !important; +} + +.deep-orange.darken-3 { + background-color: #d84315 !important; +} + +.deep-orange-text.text-darken-3 { + color: #d84315 !important; +} + +.deep-orange.darken-4 { + background-color: #bf360c !important; +} + +.deep-orange-text.text-darken-4 { + color: #bf360c !important; +} + +.deep-orange.accent-1 { + background-color: #ff9e80 !important; +} + +.deep-orange-text.text-accent-1 { + color: #ff9e80 !important; +} + +.deep-orange.accent-2 { + background-color: #ff6e40 !important; +} + +.deep-orange-text.text-accent-2 { + color: #ff6e40 !important; +} + +.deep-orange.accent-3 { + background-color: #ff3d00 !important; +} + +.deep-orange-text.text-accent-3 { + color: #ff3d00 !important; +} + +.deep-orange.accent-4 { + background-color: #dd2c00 !important; +} + +.deep-orange-text.text-accent-4 { + color: #dd2c00 !important; +} + +.brown { + background-color: #795548 !important; +} + +.brown-text { + color: #795548 !important; +} + +.brown.lighten-5 { + background-color: #efebe9 !important; +} + +.brown-text.text-lighten-5 { + color: #efebe9 !important; +} + +.brown.lighten-4 { + background-color: #d7ccc8 !important; +} + +.brown-text.text-lighten-4 { + color: #d7ccc8 !important; +} + +.brown.lighten-3 { + background-color: #bcaaa4 !important; +} + +.brown-text.text-lighten-3 { + color: #bcaaa4 !important; +} + +.brown.lighten-2 { + background-color: #a1887f !important; +} + +.brown-text.text-lighten-2 { + color: #a1887f !important; +} + +.brown.lighten-1 { + background-color: #8d6e63 !important; +} + +.brown-text.text-lighten-1 { + color: #8d6e63 !important; +} + +.brown.darken-1 { + background-color: #6d4c41 !important; +} + +.brown-text.text-darken-1 { + color: #6d4c41 !important; +} + +.brown.darken-2 { + background-color: #5d4037 !important; +} + +.brown-text.text-darken-2 { + color: #5d4037 !important; +} + +.brown.darken-3 { + background-color: #4e342e !important; +} + +.brown-text.text-darken-3 { + color: #4e342e !important; +} + +.brown.darken-4 { + background-color: #3e2723 !important; +} + +.brown-text.text-darken-4 { + color: #3e2723 !important; +} + +.blue-grey { + background-color: #607d8b !important; +} + +.blue-grey-text { + color: #607d8b !important; +} + +.blue-grey.lighten-5 { + background-color: #eceff1 !important; +} + +.blue-grey-text.text-lighten-5 { + color: #eceff1 !important; +} + +.blue-grey.lighten-4 { + background-color: #cfd8dc !important; +} + +.blue-grey-text.text-lighten-4 { + color: #cfd8dc !important; +} + +.blue-grey.lighten-3 { + background-color: #b0bec5 !important; +} + +.blue-grey-text.text-lighten-3 { + color: #b0bec5 !important; +} + +.blue-grey.lighten-2 { + background-color: #90a4ae !important; +} + +.blue-grey-text.text-lighten-2 { + color: #90a4ae !important; +} + +.blue-grey.lighten-1 { + background-color: #78909c !important; +} + +.blue-grey-text.text-lighten-1 { + color: #78909c !important; +} + +.blue-grey.darken-1 { + background-color: #546e7a !important; +} + +.blue-grey-text.text-darken-1 { + color: #546e7a !important; +} + +.blue-grey.darken-2 { + background-color: #455a64 !important; +} + +.blue-grey-text.text-darken-2 { + color: #455a64 !important; +} + +.blue-grey.darken-3 { + background-color: #37474f !important; +} + +.blue-grey-text.text-darken-3 { + color: #37474f !important; +} + +.blue-grey.darken-4 { + background-color: #263238 !important; +} + +.blue-grey-text.text-darken-4 { + color: #263238 !important; +} + +.grey { + background-color: #9e9e9e !important; +} + +.grey-text { + color: #9e9e9e !important; +} + +.grey.lighten-5 { + background-color: #fafafa !important; +} + +.grey-text.text-lighten-5 { + color: #fafafa !important; +} + +.grey.lighten-4 { + background-color: #f5f5f5 !important; +} + +.grey-text.text-lighten-4 { + color: #f5f5f5 !important; +} + +.grey.lighten-3 { + background-color: #eeeeee !important; +} + +.grey-text.text-lighten-3 { + color: #eeeeee !important; +} + +.grey.lighten-2 { + background-color: #e0e0e0 !important; +} + +.grey-text.text-lighten-2 { + color: #e0e0e0 !important; +} + +.grey.lighten-1 { + background-color: #bdbdbd !important; +} + +.grey-text.text-lighten-1 { + color: #bdbdbd !important; +} + +.grey.darken-1 { + background-color: #757575 !important; +} + +.grey-text.text-darken-1 { + color: #757575 !important; +} + +.grey.darken-2 { + background-color: #616161 !important; +} + +.grey-text.text-darken-2 { + color: #616161 !important; +} + +.grey.darken-3 { + background-color: #424242 !important; +} + +.grey-text.text-darken-3 { + color: #424242 !important; +} + +.grey.darken-4 { + background-color: #212121 !important; +} + +.grey-text.text-darken-4 { + color: #212121 !important; +} + +.black { + background-color: #000000 !important; +} + +.black-text { + color: #000000 !important; +} + +.white { + background-color: #FFFFFF !important; +} + +.white-text { + color: #FFFFFF !important; +} + +.transparent { + background-color: transparent !important; +} + +.transparent-text { + color: transparent !important; +} + +/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ +/* Document + ========================================================================== */ +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ +html { + line-height: 1.15; + /* 1 */ + -ms-text-size-adjust: 100%; + /* 2 */ + -webkit-text-size-adjust: 100%; + /* 2 */ +} + +/* Sections + ========================================================================== */ +/** + * Remove the margin in all browsers (opinionated). + */ +body { + margin: 0; +} + +/** + * Add the correct display in IE 9-. + */ +article, +aside, +footer, +header, +nav, +section { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ +/** + * Add the correct display in IE 9-. + * 1. Add the correct display in IE. + */ +figcaption, +figure, +main { + /* 1 */ + display: block; +} + +/** + * Add the correct margin in IE 8. + */ +figure { + margin: 1em 40px; +} + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ +hr { + -webkit-box-sizing: content-box; + box-sizing: content-box; + /* 1 */ + height: 0; + /* 1 */ + overflow: visible; + /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ +pre { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ +/** + * 1. Remove the gray background on active links in IE 10. + * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. + */ +a { + background-color: transparent; + /* 1 */ + -webkit-text-decoration-skip: objects; + /* 2 */ +} + +/** + * 1. Remove the bottom border in Chrome 57- and Firefox 39-. + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ +abbr[title] { + border-bottom: none; + /* 1 */ + text-decoration: underline; + /* 2 */ + -webkit-text-decoration: underline dotted; + -moz-text-decoration: underline dotted; + text-decoration: underline dotted; + /* 2 */ +} + +/** + * Prevent the duplicate application of `bolder` by the next rule in Safari 6. + */ +b, +strong { + font-weight: inherit; +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ +code, +kbd, +samp { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/** + * Add the correct font style in Android 4.3-. + */ +dfn { + font-style: italic; +} + +/** + * Add the correct background and color in IE 9-. + */ +mark { + background-color: #ff0; + color: #000; +} + +/** + * Add the correct font size in all browsers. + */ +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ +/** + * Add the correct display in IE 9-. + */ +audio, +video { + display: inline-block; +} + +/** + * Add the correct display in iOS 4-7. + */ +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Remove the border on images inside links in IE 10-. + */ +img { + border-style: none; +} + +/** + * Hide the overflow in IE. + */ +svg:not(:root) { + overflow: hidden; +} + +/* Forms + ========================================================================== */ +/** + * 1. Change the font styles in all browsers (opinionated). + * 2. Remove the margin in Firefox and Safari. + */ +button, +input, +optgroup, +select, +textarea { + font-family: sans-serif; + /* 1 */ + font-size: 100%; + /* 1 */ + line-height: 1.15; + /* 1 */ + margin: 0; + /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ +button, +input { + /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ +button, +select { + /* 1 */ + text-transform: none; +} + +/** + * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` + * controls in Android 4. + * 2. Correct the inability to style clickable types in iOS and Safari. + */ +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; + /* 2 */ +} + +/** + * Remove the inner border and padding in Firefox. + */ +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ +legend { + -webkit-box-sizing: border-box; + box-sizing: border-box; + /* 1 */ + color: inherit; + /* 2 */ + display: table; + /* 1 */ + max-width: 100%; + /* 1 */ + padding: 0; + /* 3 */ + white-space: normal; + /* 1 */ +} + +/** + * 1. Add the correct display in IE 9-. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ +progress { + display: inline-block; + /* 1 */ + vertical-align: baseline; + /* 2 */ +} + +/** + * Remove the default vertical scrollbar in IE. + */ +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10-. + * 2. Remove the padding in IE 10-. + */ +[type="checkbox"], +[type="radio"] { + -webkit-box-sizing: border-box; + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ +[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/** + * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. + */ +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* Interactive + ========================================================================== */ +/* + * Add the correct display in IE 9-. + * 1. Add the correct display in Edge, IE, and Firefox. + */ +details, +menu { + display: block; +} + +/* + * Add the correct display in all browsers. + */ +summary { + display: list-item; +} + +/* Scripting + ========================================================================== */ +/** + * Add the correct display in IE 9-. + */ +canvas { + display: inline-block; +} + +/** + * Add the correct display in IE. + */ +template { + display: none; +} + +/* Hidden + ========================================================================== */ +/** + * Add the correct display in IE 10-. + */ +[hidden] { + display: none; +} + +html { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +*, *:before, *:after { + -webkit-box-sizing: inherit; + box-sizing: inherit; +} + +button, +input, +optgroup, +select, +textarea { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +} + +ul:not(.browser-default) { + padding-left: 0; + list-style-type: none; +} + +ul:not(.browser-default) > li { + list-style-type: none; +} + +a { + color: #039be5; + text-decoration: none; + -webkit-tap-highlight-color: transparent; +} + +.valign-wrapper { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; +} + +.clearfix { + clear: both; +} + +.z-depth-0 { + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +/* 2dp elevation modified*/ +.z-depth-1, nav, .card-panel, .card, .toast, .btn, .btn-large, .btn-small, .btn-floating, .dropdown-content, .collapsible, .sidenav { + -webkit-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2); +} + +.z-depth-1-half, .btn:hover, .btn-large:hover, .btn-small:hover, .btn-floating:hover { + -webkit-box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14), 0 1px 7px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -1px rgba(0, 0, 0, 0.2); + box-shadow: 0 3px 3px 0 rgba(0, 0, 0, 0.14), 0 1px 7px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -1px rgba(0, 0, 0, 0.2); +} + +/* 6dp elevation modified*/ +.z-depth-2 { + -webkit-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3); + box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.3); +} + +/* 12dp elevation modified*/ +.z-depth-3 { + -webkit-box-shadow: 0 8px 17px 2px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); + box-shadow: 0 8px 17px 2px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2); +} + +/* 16dp elevation */ +.z-depth-4 { + -webkit-box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -7px rgba(0, 0, 0, 0.2); + box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -7px rgba(0, 0, 0, 0.2); +} + +/* 24dp elevation */ +.z-depth-5, .modal { + -webkit-box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12), 0 11px 15px -7px rgba(0, 0, 0, 0.2); + box-shadow: 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12), 0 11px 15px -7px rgba(0, 0, 0, 0.2); +} + +.hoverable { + -webkit-transition: -webkit-box-shadow .25s; + transition: -webkit-box-shadow .25s; + transition: box-shadow .25s; + transition: box-shadow .25s, -webkit-box-shadow .25s; +} + +.hoverable:hover { + -webkit-box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); +} + +.divider { + height: 1px; + overflow: hidden; + background-color: #e0e0e0; +} + +blockquote { + margin: 20px 0; + padding-left: 1.5rem; + border-left: 5px solid #ee6e73; +} + +i { + line-height: inherit; +} + +i.left { + float: left; + margin-right: 15px; +} + +i.right { + float: right; + margin-left: 15px; +} + +i.tiny { + font-size: 1rem; +} + +i.small { + font-size: 2rem; +} + +i.medium { + font-size: 4rem; +} + +i.large { + font-size: 6rem; +} + +img.responsive-img, +video.responsive-video { + max-width: 100%; + height: auto; +} + +.pagination li { + display: inline-block; + border-radius: 2px; + text-align: center; + vertical-align: top; + height: 30px; +} + +.pagination li a { + color: #444; + display: inline-block; + font-size: 1.2rem; + padding: 0 10px; + line-height: 30px; +} + +.pagination li.active a { + color: #fff; +} + +.pagination li.active { + background-color: #ee6e73; +} + +.pagination li.disabled a { + cursor: default; + color: #999; +} + +.pagination li i { + font-size: 2rem; +} + +.pagination li.pages ul li { + display: inline-block; + float: none; +} + +@media only screen and (max-width: 992px) { + .pagination { + width: 100%; + } + .pagination li.prev, + .pagination li.next { + width: 10%; + } + .pagination li.pages { + width: 80%; + overflow: hidden; + white-space: nowrap; + } +} + +.breadcrumb { + font-size: 18px; + color: rgba(255, 255, 255, 0.7); +} + +.breadcrumb i, +.breadcrumb [class^="mdi-"], .breadcrumb [class*="mdi-"], +.breadcrumb i.material-icons { + display: inline-block; + float: left; + font-size: 24px; +} + +.breadcrumb:before { + content: '\E5CC'; + color: rgba(255, 255, 255, 0.7); + vertical-align: top; + display: inline-block; + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 25px; + margin: 0 10px 0 8px; + -webkit-font-smoothing: antialiased; +} + +.breadcrumb:first-child:before { + display: none; +} + +.breadcrumb:last-child { + color: #fff; +} + +.parallax-container { + position: relative; + overflow: hidden; + height: 500px; +} + +.parallax-container .parallax { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: -1; +} + +.parallax-container .parallax img { + opacity: 0; + position: absolute; + left: 50%; + bottom: 0; + min-width: 100%; + min-height: 100%; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + -webkit-transform: translateX(-50%); + transform: translateX(-50%); +} + +.pin-top, .pin-bottom { + position: relative; +} + +.pinned { + position: fixed !important; +} + +/********************* + Transition Classes +**********************/ +ul.staggered-list li { + opacity: 0; +} + +.fade-in { + opacity: 0; + -webkit-transform-origin: 0 50%; + transform-origin: 0 50%; +} + +/********************* + Media Query Classes +**********************/ +@media only screen and (max-width: 600px) { + .hide-on-small-only, .hide-on-small-and-down { + display: none !important; + } +} + +@media only screen and (max-width: 992px) { + .hide-on-med-and-down { + display: none !important; + } +} + +@media only screen and (min-width: 601px) { + .hide-on-med-and-up { + display: none !important; + } +} + +@media only screen and (min-width: 600px) and (max-width: 992px) { + .hide-on-med-only { + display: none !important; + } +} + +@media only screen and (min-width: 993px) { + .hide-on-large-only { + display: none !important; + } +} + +@media only screen and (min-width: 1201px) { + .hide-on-extra-large-only { + display: none !important; + } +} + +@media only screen and (min-width: 1201px) { + .show-on-extra-large { + display: block !important; + } +} + +@media only screen and (min-width: 993px) { + .show-on-large { + display: block !important; + } +} + +@media only screen and (min-width: 600px) and (max-width: 992px) { + .show-on-medium { + display: block !important; + } +} + +@media only screen and (max-width: 600px) { + .show-on-small { + display: block !important; + } +} + +@media only screen and (min-width: 601px) { + .show-on-medium-and-up { + display: block !important; + } +} + +@media only screen and (max-width: 992px) { + .show-on-medium-and-down { + display: block !important; + } +} + +@media only screen and (max-width: 600px) { + .center-on-small-only { + text-align: center; + } +} + +.page-footer { + padding-top: 20px; + color: #fff; + background-color: #ee6e73; +} + +.page-footer .footer-copyright { + overflow: hidden; + min-height: 50px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 10px 0px; + color: rgba(255, 255, 255, 0.8); + background-color: rgba(51, 51, 51, 0.08); +} + +table, th, td { + border: none; +} + +table { + width: 100%; + display: table; + border-collapse: collapse; + border-spacing: 0; +} + +table.striped tr { + border-bottom: none; +} + +table.striped > tbody > tr:nth-child(odd) { + background-color: rgba(242, 242, 242, 0.5); +} + +table.striped > tbody > tr > td { + border-radius: 0; +} + +table.highlight > tbody > tr { + -webkit-transition: background-color .25s ease; + transition: background-color .25s ease; +} + +table.highlight > tbody > tr:hover { + background-color: rgba(242, 242, 242, 0.5); +} + +table.centered thead tr th, table.centered tbody tr td { + text-align: center; +} + +tr { + border-bottom: 1px solid rgba(0, 0, 0, 0.12); +} + +td, th { + padding: 15px 5px; + display: table-cell; + text-align: left; + vertical-align: middle; + border-radius: 2px; +} + +@media only screen and (max-width: 992px) { + table.responsive-table { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + display: block; + position: relative; + /* sort out borders */ + } + table.responsive-table td:empty:before { + content: '\00a0'; + } + table.responsive-table th, + table.responsive-table td { + margin: 0; + vertical-align: top; + } + table.responsive-table th { + text-align: left; + } + table.responsive-table thead { + display: block; + float: left; + } + table.responsive-table thead tr { + display: block; + padding: 0 10px 0 0; + } + table.responsive-table thead tr th::before { + content: "\00a0"; + } + table.responsive-table tbody { + display: block; + width: auto; + position: relative; + overflow-x: auto; + white-space: nowrap; + } + table.responsive-table tbody tr { + display: inline-block; + vertical-align: top; + } + table.responsive-table th { + display: block; + text-align: right; + } + table.responsive-table td { + display: block; + min-height: 1.25em; + text-align: left; + } + table.responsive-table tr { + border-bottom: none; + padding: 0 10px; + } + table.responsive-table thead { + border: 0; + border-right: 1px solid rgba(0, 0, 0, 0.12); + } +} + +.collection { + margin: 0.5rem 0 1rem 0; + border: 1px solid #e0e0e0; + border-radius: 2px; + overflow: hidden; + position: relative; +} + +.collection .collection-item { + background-color: #fff; + line-height: 1.5rem; + padding: 10px 20px; + margin: 0; + border-bottom: 1px solid #e0e0e0; +} + +.collection .collection-item.avatar { + min-height: 84px; + padding-left: 72px; + position: relative; +} + +.collection .collection-item.avatar:not(.circle-clipper) > .circle, +.collection .collection-item.avatar :not(.circle-clipper) > .circle { + position: absolute; + width: 42px; + height: 42px; + overflow: hidden; + left: 15px; + display: inline-block; + vertical-align: middle; +} + +.collection .collection-item.avatar i.circle { + font-size: 18px; + line-height: 42px; + color: #fff; + background-color: #999; + text-align: center; +} + +.collection .collection-item.avatar .title { + font-size: 16px; +} + +.collection .collection-item.avatar p { + margin: 0; +} + +.collection .collection-item.avatar .secondary-content { + position: absolute; + top: 16px; + right: 16px; +} + +.collection .collection-item:last-child { + border-bottom: none; +} + +.collection .collection-item.active { + background-color: #26a69a; + color: #eafaf9; +} + +.collection .collection-item.active .secondary-content { + color: #fff; +} + +.collection a.collection-item { + display: block; + -webkit-transition: .25s; + transition: .25s; + color: #26a69a; +} + +.collection a.collection-item:not(.active):hover { + background-color: #ddd; +} + +.collection.with-header .collection-header { + background-color: #fff; + border-bottom: 1px solid #e0e0e0; + padding: 10px 20px; +} + +.collection.with-header .collection-item { + padding-left: 30px; +} + +.collection.with-header .collection-item.avatar { + padding-left: 72px; +} + +.secondary-content { + float: right; + color: #26a69a; +} + +.collapsible .collection { + margin: 0; + border: none; +} + +.video-container { + position: relative; + padding-bottom: 56.25%; + height: 0; + overflow: hidden; +} + +.video-container iframe, .video-container object, .video-container embed { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.progress { + position: relative; + height: 4px; + display: block; + width: 100%; + background-color: #acece6; + border-radius: 2px; + margin: 0.5rem 0 1rem 0; + overflow: hidden; +} + +.progress .determinate { + position: absolute; + top: 0; + left: 0; + bottom: 0; + background-color: #26a69a; + -webkit-transition: width .3s linear; + transition: width .3s linear; +} + +.progress .indeterminate { + background-color: #26a69a; +} + +.progress .indeterminate:before { + content: ''; + position: absolute; + background-color: inherit; + top: 0; + left: 0; + bottom: 0; + will-change: left, right; + -webkit-animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; + animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite; +} + +.progress .indeterminate:after { + content: ''; + position: absolute; + background-color: inherit; + top: 0; + left: 0; + bottom: 0; + will-change: left, right; + -webkit-animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; + animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite; + -webkit-animation-delay: 1.15s; + animation-delay: 1.15s; +} + +@-webkit-keyframes indeterminate { + 0% { + left: -35%; + right: 100%; + } + 60% { + left: 100%; + right: -90%; + } + 100% { + left: 100%; + right: -90%; + } +} + +@keyframes indeterminate { + 0% { + left: -35%; + right: 100%; + } + 60% { + left: 100%; + right: -90%; + } + 100% { + left: 100%; + right: -90%; + } +} + +@-webkit-keyframes indeterminate-short { + 0% { + left: -200%; + right: 100%; + } + 60% { + left: 107%; + right: -8%; + } + 100% { + left: 107%; + right: -8%; + } +} + +@keyframes indeterminate-short { + 0% { + left: -200%; + right: 100%; + } + 60% { + left: 107%; + right: -8%; + } + 100% { + left: 107%; + right: -8%; + } +} + +/******************* + Utility Classes +*******************/ +.hide { + display: none !important; +} + +.left-align { + text-align: left; +} + +.right-align { + text-align: right; +} + +.center, .center-align { + text-align: center; +} + +.left { + float: left !important; +} + +.right { + float: right !important; +} + +.no-select, input[type=range], +input[type=range] + .thumb { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.circle { + border-radius: 50%; +} + +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} + +.truncate { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.no-padding { + padding: 0 !important; +} + +span.badge { + min-width: 3rem; + padding: 0 6px; + margin-left: 14px; + text-align: center; + font-size: 1rem; + line-height: 22px; + height: 22px; + color: #757575; + float: right; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +span.badge.new { + font-weight: 300; + font-size: 0.8rem; + color: #fff; + background-color: #26a69a; + border-radius: 2px; +} + +span.badge.new:after { + content: " new"; +} + +span.badge[data-badge-caption]::after { + content: " " attr(data-badge-caption); +} + +nav ul a span.badge { + display: inline-block; + float: none; + margin-left: 4px; + line-height: 22px; + height: 22px; + -webkit-font-smoothing: auto; +} + +.collection-item span.badge { + margin-top: calc(0.75rem - 11px); +} + +.collapsible span.badge { + margin-left: auto; +} + +.sidenav span.badge { + margin-top: calc(24px - 11px); +} + +table span.badge { + display: inline-block; + float: none; + margin-left: auto; +} + +/* This is needed for some mobile phones to display the Google Icon font properly */ +.material-icons { + text-rendering: optimizeLegibility; + -webkit-font-feature-settings: 'liga'; + -moz-font-feature-settings: 'liga'; + font-feature-settings: 'liga'; +} + +.container { + margin: 0 auto; + max-width: 1280px; + width: 90%; +} + +@media only screen and (min-width: 601px) { + .container { + width: 85%; + } +} + +@media only screen and (min-width: 993px) { + .container { + width: 70%; + } +} + +.col .row { + margin-left: -0.75rem; + margin-right: -0.75rem; +} + +.section { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.section.no-pad { + padding: 0; +} + +.section.no-pad-bot { + padding-bottom: 0; +} + +.section.no-pad-top { + padding-top: 0; +} + +.row { + margin-left: auto; + margin-right: auto; + margin-bottom: 20px; +} + +.row:after { + content: ""; + display: table; + clear: both; +} + +.row .col { + float: left; + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 0 0.75rem; + min-height: 1px; +} + +.row .col[class*="push-"], .row .col[class*="pull-"] { + position: relative; +} + +.row .col.s1 { + width: 8.3333333333%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s2 { + width: 16.6666666667%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s3 { + width: 25%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s4 { + width: 33.3333333333%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s5 { + width: 41.6666666667%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s6 { + width: 50%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s7 { + width: 58.3333333333%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s8 { + width: 66.6666666667%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s9 { + width: 75%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s10 { + width: 83.3333333333%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s11 { + width: 91.6666666667%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.s12 { + width: 100%; + margin-left: auto; + left: auto; + right: auto; +} + +.row .col.offset-s1 { + margin-left: 8.3333333333%; +} + +.row .col.pull-s1 { + right: 8.3333333333%; +} + +.row .col.push-s1 { + left: 8.3333333333%; +} + +.row .col.offset-s2 { + margin-left: 16.6666666667%; +} + +.row .col.pull-s2 { + right: 16.6666666667%; +} + +.row .col.push-s2 { + left: 16.6666666667%; +} + +.row .col.offset-s3 { + margin-left: 25%; +} + +.row .col.pull-s3 { + right: 25%; +} + +.row .col.push-s3 { + left: 25%; +} + +.row .col.offset-s4 { + margin-left: 33.3333333333%; +} + +.row .col.pull-s4 { + right: 33.3333333333%; +} + +.row .col.push-s4 { + left: 33.3333333333%; +} + +.row .col.offset-s5 { + margin-left: 41.6666666667%; +} + +.row .col.pull-s5 { + right: 41.6666666667%; +} + +.row .col.push-s5 { + left: 41.6666666667%; +} + +.row .col.offset-s6 { + margin-left: 50%; +} + +.row .col.pull-s6 { + right: 50%; +} + +.row .col.push-s6 { + left: 50%; +} + +.row .col.offset-s7 { + margin-left: 58.3333333333%; +} + +.row .col.pull-s7 { + right: 58.3333333333%; +} + +.row .col.push-s7 { + left: 58.3333333333%; +} + +.row .col.offset-s8 { + margin-left: 66.6666666667%; +} + +.row .col.pull-s8 { + right: 66.6666666667%; +} + +.row .col.push-s8 { + left: 66.6666666667%; +} + +.row .col.offset-s9 { + margin-left: 75%; +} + +.row .col.pull-s9 { + right: 75%; +} + +.row .col.push-s9 { + left: 75%; +} + +.row .col.offset-s10 { + margin-left: 83.3333333333%; +} + +.row .col.pull-s10 { + right: 83.3333333333%; +} + +.row .col.push-s10 { + left: 83.3333333333%; +} + +.row .col.offset-s11 { + margin-left: 91.6666666667%; +} + +.row .col.pull-s11 { + right: 91.6666666667%; +} + +.row .col.push-s11 { + left: 91.6666666667%; +} + +.row .col.offset-s12 { + margin-left: 100%; +} + +.row .col.pull-s12 { + right: 100%; +} + +.row .col.push-s12 { + left: 100%; +} + +@media only screen and (min-width: 601px) { + .row .col.m1 { + width: 8.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m2 { + width: 16.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m3 { + width: 25%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m4 { + width: 33.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m5 { + width: 41.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m6 { + width: 50%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m7 { + width: 58.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m8 { + width: 66.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m9 { + width: 75%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m10 { + width: 83.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m11 { + width: 91.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.m12 { + width: 100%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.offset-m1 { + margin-left: 8.3333333333%; + } + .row .col.pull-m1 { + right: 8.3333333333%; + } + .row .col.push-m1 { + left: 8.3333333333%; + } + .row .col.offset-m2 { + margin-left: 16.6666666667%; + } + .row .col.pull-m2 { + right: 16.6666666667%; + } + .row .col.push-m2 { + left: 16.6666666667%; + } + .row .col.offset-m3 { + margin-left: 25%; + } + .row .col.pull-m3 { + right: 25%; + } + .row .col.push-m3 { + left: 25%; + } + .row .col.offset-m4 { + margin-left: 33.3333333333%; + } + .row .col.pull-m4 { + right: 33.3333333333%; + } + .row .col.push-m4 { + left: 33.3333333333%; + } + .row .col.offset-m5 { + margin-left: 41.6666666667%; + } + .row .col.pull-m5 { + right: 41.6666666667%; + } + .row .col.push-m5 { + left: 41.6666666667%; + } + .row .col.offset-m6 { + margin-left: 50%; + } + .row .col.pull-m6 { + right: 50%; + } + .row .col.push-m6 { + left: 50%; + } + .row .col.offset-m7 { + margin-left: 58.3333333333%; + } + .row .col.pull-m7 { + right: 58.3333333333%; + } + .row .col.push-m7 { + left: 58.3333333333%; + } + .row .col.offset-m8 { + margin-left: 66.6666666667%; + } + .row .col.pull-m8 { + right: 66.6666666667%; + } + .row .col.push-m8 { + left: 66.6666666667%; + } + .row .col.offset-m9 { + margin-left: 75%; + } + .row .col.pull-m9 { + right: 75%; + } + .row .col.push-m9 { + left: 75%; + } + .row .col.offset-m10 { + margin-left: 83.3333333333%; + } + .row .col.pull-m10 { + right: 83.3333333333%; + } + .row .col.push-m10 { + left: 83.3333333333%; + } + .row .col.offset-m11 { + margin-left: 91.6666666667%; + } + .row .col.pull-m11 { + right: 91.6666666667%; + } + .row .col.push-m11 { + left: 91.6666666667%; + } + .row .col.offset-m12 { + margin-left: 100%; + } + .row .col.pull-m12 { + right: 100%; + } + .row .col.push-m12 { + left: 100%; + } +} + +@media only screen and (min-width: 993px) { + .row .col.l1 { + width: 8.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l2 { + width: 16.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l3 { + width: 25%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l4 { + width: 33.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l5 { + width: 41.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l6 { + width: 50%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l7 { + width: 58.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l8 { + width: 66.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l9 { + width: 75%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l10 { + width: 83.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l11 { + width: 91.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.l12 { + width: 100%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.offset-l1 { + margin-left: 8.3333333333%; + } + .row .col.pull-l1 { + right: 8.3333333333%; + } + .row .col.push-l1 { + left: 8.3333333333%; + } + .row .col.offset-l2 { + margin-left: 16.6666666667%; + } + .row .col.pull-l2 { + right: 16.6666666667%; + } + .row .col.push-l2 { + left: 16.6666666667%; + } + .row .col.offset-l3 { + margin-left: 25%; + } + .row .col.pull-l3 { + right: 25%; + } + .row .col.push-l3 { + left: 25%; + } + .row .col.offset-l4 { + margin-left: 33.3333333333%; + } + .row .col.pull-l4 { + right: 33.3333333333%; + } + .row .col.push-l4 { + left: 33.3333333333%; + } + .row .col.offset-l5 { + margin-left: 41.6666666667%; + } + .row .col.pull-l5 { + right: 41.6666666667%; + } + .row .col.push-l5 { + left: 41.6666666667%; + } + .row .col.offset-l6 { + margin-left: 50%; + } + .row .col.pull-l6 { + right: 50%; + } + .row .col.push-l6 { + left: 50%; + } + .row .col.offset-l7 { + margin-left: 58.3333333333%; + } + .row .col.pull-l7 { + right: 58.3333333333%; + } + .row .col.push-l7 { + left: 58.3333333333%; + } + .row .col.offset-l8 { + margin-left: 66.6666666667%; + } + .row .col.pull-l8 { + right: 66.6666666667%; + } + .row .col.push-l8 { + left: 66.6666666667%; + } + .row .col.offset-l9 { + margin-left: 75%; + } + .row .col.pull-l9 { + right: 75%; + } + .row .col.push-l9 { + left: 75%; + } + .row .col.offset-l10 { + margin-left: 83.3333333333%; + } + .row .col.pull-l10 { + right: 83.3333333333%; + } + .row .col.push-l10 { + left: 83.3333333333%; + } + .row .col.offset-l11 { + margin-left: 91.6666666667%; + } + .row .col.pull-l11 { + right: 91.6666666667%; + } + .row .col.push-l11 { + left: 91.6666666667%; + } + .row .col.offset-l12 { + margin-left: 100%; + } + .row .col.pull-l12 { + right: 100%; + } + .row .col.push-l12 { + left: 100%; + } +} + +@media only screen and (min-width: 1201px) { + .row .col.xl1 { + width: 8.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl2 { + width: 16.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl3 { + width: 25%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl4 { + width: 33.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl5 { + width: 41.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl6 { + width: 50%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl7 { + width: 58.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl8 { + width: 66.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl9 { + width: 75%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl10 { + width: 83.3333333333%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl11 { + width: 91.6666666667%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.xl12 { + width: 100%; + margin-left: auto; + left: auto; + right: auto; + } + .row .col.offset-xl1 { + margin-left: 8.3333333333%; + } + .row .col.pull-xl1 { + right: 8.3333333333%; + } + .row .col.push-xl1 { + left: 8.3333333333%; + } + .row .col.offset-xl2 { + margin-left: 16.6666666667%; + } + .row .col.pull-xl2 { + right: 16.6666666667%; + } + .row .col.push-xl2 { + left: 16.6666666667%; + } + .row .col.offset-xl3 { + margin-left: 25%; + } + .row .col.pull-xl3 { + right: 25%; + } + .row .col.push-xl3 { + left: 25%; + } + .row .col.offset-xl4 { + margin-left: 33.3333333333%; + } + .row .col.pull-xl4 { + right: 33.3333333333%; + } + .row .col.push-xl4 { + left: 33.3333333333%; + } + .row .col.offset-xl5 { + margin-left: 41.6666666667%; + } + .row .col.pull-xl5 { + right: 41.6666666667%; + } + .row .col.push-xl5 { + left: 41.6666666667%; + } + .row .col.offset-xl6 { + margin-left: 50%; + } + .row .col.pull-xl6 { + right: 50%; + } + .row .col.push-xl6 { + left: 50%; + } + .row .col.offset-xl7 { + margin-left: 58.3333333333%; + } + .row .col.pull-xl7 { + right: 58.3333333333%; + } + .row .col.push-xl7 { + left: 58.3333333333%; + } + .row .col.offset-xl8 { + margin-left: 66.6666666667%; + } + .row .col.pull-xl8 { + right: 66.6666666667%; + } + .row .col.push-xl8 { + left: 66.6666666667%; + } + .row .col.offset-xl9 { + margin-left: 75%; + } + .row .col.pull-xl9 { + right: 75%; + } + .row .col.push-xl9 { + left: 75%; + } + .row .col.offset-xl10 { + margin-left: 83.3333333333%; + } + .row .col.pull-xl10 { + right: 83.3333333333%; + } + .row .col.push-xl10 { + left: 83.3333333333%; + } + .row .col.offset-xl11 { + margin-left: 91.6666666667%; + } + .row .col.pull-xl11 { + right: 91.6666666667%; + } + .row .col.push-xl11 { + left: 91.6666666667%; + } + .row .col.offset-xl12 { + margin-left: 100%; + } + .row .col.pull-xl12 { + right: 100%; + } + .row .col.push-xl12 { + left: 100%; + } +} + +nav { + color: #fff; + background-color: #ee6e73; + width: 100%; + height: 56px; + line-height: 56px; +} + +nav.nav-extended { + height: auto; +} + +nav.nav-extended .nav-wrapper { + min-height: 56px; + height: auto; +} + +nav.nav-extended .nav-content { + position: relative; + line-height: normal; +} + +nav a { + color: #fff; +} + +nav i, +nav [class^="mdi-"], nav [class*="mdi-"], +nav i.material-icons { + display: block; + font-size: 24px; + height: 56px; + line-height: 56px; +} + +nav .nav-wrapper { + position: relative; + height: 100%; +} + +@media only screen and (min-width: 993px) { + nav a.sidenav-trigger { + display: none; + } +} + +nav .sidenav-trigger { + float: left; + position: relative; + z-index: 1; + height: 56px; + margin: 0 18px; +} + +nav .sidenav-trigger i { + height: 56px; + line-height: 56px; +} + +nav .brand-logo { + position: absolute; + color: #fff; + display: inline-block; + font-size: 2.1rem; + padding: 0; +} + +nav .brand-logo.center { + left: 50%; + -webkit-transform: translateX(-50%); + transform: translateX(-50%); +} + +@media only screen and (max-width: 992px) { + nav .brand-logo { + left: 50%; + -webkit-transform: translateX(-50%); + transform: translateX(-50%); + } + nav .brand-logo.left, nav .brand-logo.right { + padding: 0; + -webkit-transform: none; + transform: none; + } + nav .brand-logo.left { + left: 0.5rem; + } + nav .brand-logo.right { + right: 0.5rem; + left: auto; + } +} + +nav .brand-logo.right { + right: 0.5rem; + padding: 0; +} + +nav .brand-logo i, +nav .brand-logo [class^="mdi-"], nav .brand-logo [class*="mdi-"], +nav .brand-logo i.material-icons { + float: left; + margin-right: 15px; +} + +nav .nav-title { + display: inline-block; + font-size: 32px; + padding: 28px 0; +} + +nav ul { + margin: 0; +} + +nav ul li { + -webkit-transition: background-color .3s; + transition: background-color .3s; + float: left; + padding: 0; +} + +nav ul li.active { + background-color: rgba(0, 0, 0, 0.1); +} + +nav ul a { + -webkit-transition: background-color .3s; + transition: background-color .3s; + font-size: 1rem; + color: #fff; + display: block; + padding: 0 15px; + cursor: pointer; +} + +nav ul a.btn, nav ul a.btn-large, nav ul a.btn-small, nav ul a.btn-large, nav ul a.btn-flat, nav ul a.btn-floating { + margin-top: -2px; + margin-left: 15px; + margin-right: 15px; +} + +nav ul a.btn > .material-icons, nav ul a.btn-large > .material-icons, nav ul a.btn-small > .material-icons, nav ul a.btn-large > .material-icons, nav ul a.btn-flat > .material-icons, nav ul a.btn-floating > .material-icons { + height: inherit; + line-height: inherit; +} + +nav ul a:hover { + background-color: rgba(0, 0, 0, 0.1); +} + +nav ul.left { + float: left; +} + +nav form { + height: 100%; +} + +nav .input-field { + margin: 0; + height: 100%; +} + +nav .input-field input { + height: 100%; + font-size: 1.2rem; + border: none; + padding-left: 2rem; +} + +nav .input-field input:focus, nav .input-field input[type=text]:valid, nav .input-field input[type=password]:valid, nav .input-field input[type=email]:valid, nav .input-field input[type=url]:valid, nav .input-field input[type=date]:valid { + border: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +nav .input-field label { + top: 0; + left: 0; +} + +nav .input-field label i { + color: rgba(255, 255, 255, 0.7); + -webkit-transition: color .3s; + transition: color .3s; +} + +nav .input-field label.active i { + color: #fff; +} + +.navbar-fixed { + position: relative; + height: 56px; + z-index: 997; +} + +.navbar-fixed nav { + position: fixed; +} + +@media only screen and (min-width: 601px) { + nav.nav-extended .nav-wrapper { + min-height: 64px; + } + nav, nav .nav-wrapper i, nav a.sidenav-trigger, nav a.sidenav-trigger i { + height: 64px; + line-height: 64px; + } + .navbar-fixed { + height: 64px; + } +} + +a { + text-decoration: none; +} + +html { + line-height: 1.5; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; + font-weight: normal; + color: rgba(0, 0, 0, 0.87); +} + +@media only screen and (min-width: 0) { + html { + font-size: 14px; + } +} + +@media only screen and (min-width: 992px) { + html { + font-size: 14.5px; + } +} + +@media only screen and (min-width: 1200px) { + html { + font-size: 15px; + } +} + +h1, h2, h3, h4, h5, h6 { + font-weight: 400; + line-height: 1.3; +} + +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + font-weight: inherit; +} + +h1 { + font-size: 4.2rem; + line-height: 110%; + margin: 2.8rem 0 1.68rem 0; +} + +h2 { + font-size: 3.56rem; + line-height: 110%; + margin: 2.3733333333rem 0 1.424rem 0; +} + +h3 { + font-size: 2.92rem; + line-height: 110%; + margin: 1.9466666667rem 0 1.168rem 0; +} + +h4 { + font-size: 2.28rem; + line-height: 110%; + margin: 1.52rem 0 0.912rem 0; +} + +h5 { + font-size: 1.64rem; + line-height: 110%; + margin: 1.0933333333rem 0 0.656rem 0; +} + +h6 { + font-size: 1.15rem; + line-height: 110%; + margin: 0.7666666667rem 0 0.46rem 0; +} + +em { + font-style: italic; +} + +strong { + font-weight: 500; +} + +small { + font-size: 75%; +} + +.light { + font-weight: 300; +} + +.thin { + font-weight: 200; +} + +@media only screen and (min-width: 360px) { + .flow-text { + font-size: 1.2rem; + } +} + +@media only screen and (min-width: 390px) { + .flow-text { + font-size: 1.224rem; + } +} + +@media only screen and (min-width: 420px) { + .flow-text { + font-size: 1.248rem; + } +} + +@media only screen and (min-width: 450px) { + .flow-text { + font-size: 1.272rem; + } +} + +@media only screen and (min-width: 480px) { + .flow-text { + font-size: 1.296rem; + } +} + +@media only screen and (min-width: 510px) { + .flow-text { + font-size: 1.32rem; + } +} + +@media only screen and (min-width: 540px) { + .flow-text { + font-size: 1.344rem; + } +} + +@media only screen and (min-width: 570px) { + .flow-text { + font-size: 1.368rem; + } +} + +@media only screen and (min-width: 600px) { + .flow-text { + font-size: 1.392rem; + } +} + +@media only screen and (min-width: 630px) { + .flow-text { + font-size: 1.416rem; + } +} + +@media only screen and (min-width: 660px) { + .flow-text { + font-size: 1.44rem; + } +} + +@media only screen and (min-width: 690px) { + .flow-text { + font-size: 1.464rem; + } +} + +@media only screen and (min-width: 720px) { + .flow-text { + font-size: 1.488rem; + } +} + +@media only screen and (min-width: 750px) { + .flow-text { + font-size: 1.512rem; + } +} + +@media only screen and (min-width: 780px) { + .flow-text { + font-size: 1.536rem; + } +} + +@media only screen and (min-width: 810px) { + .flow-text { + font-size: 1.56rem; + } +} + +@media only screen and (min-width: 840px) { + .flow-text { + font-size: 1.584rem; + } +} + +@media only screen and (min-width: 870px) { + .flow-text { + font-size: 1.608rem; + } +} + +@media only screen and (min-width: 900px) { + .flow-text { + font-size: 1.632rem; + } +} + +@media only screen and (min-width: 930px) { + .flow-text { + font-size: 1.656rem; + } +} + +@media only screen and (min-width: 960px) { + .flow-text { + font-size: 1.68rem; + } +} + +@media only screen and (max-width: 360px) { + .flow-text { + font-size: 1.2rem; + } +} + +.scale-transition { + -webkit-transition: -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; + transition: -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; + transition: transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; + transition: transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63), -webkit-transform 0.3s cubic-bezier(0.53, 0.01, 0.36, 1.63) !important; +} + +.scale-transition.scale-out { + -webkit-transform: scale(0); + transform: scale(0); + -webkit-transition: -webkit-transform .2s !important; + transition: -webkit-transform .2s !important; + transition: transform .2s !important; + transition: transform .2s, -webkit-transform .2s !important; +} + +.scale-transition.scale-in { + -webkit-transform: scale(1); + transform: scale(1); +} + +.card-panel { + -webkit-transition: -webkit-box-shadow .25s; + transition: -webkit-box-shadow .25s; + transition: box-shadow .25s; + transition: box-shadow .25s, -webkit-box-shadow .25s; + padding: 24px; + margin: 0.5rem 0 1rem 0; + border-radius: 2px; + background-color: #fff; +} + +.card { + position: relative; + margin: 0.5rem 0 1rem 0; + background-color: #fff; + -webkit-transition: -webkit-box-shadow .25s; + transition: -webkit-box-shadow .25s; + transition: box-shadow .25s; + transition: box-shadow .25s, -webkit-box-shadow .25s; + border-radius: 2px; +} + +.card .card-title { + font-size: 24px; + font-weight: 300; +} + +.card .card-title.activator { + cursor: pointer; +} + +.card.small, .card.medium, .card.large { + position: relative; +} + +.card.small .card-image, .card.medium .card-image, .card.large .card-image { + max-height: 60%; + overflow: hidden; +} + +.card.small .card-image + .card-content, .card.medium .card-image + .card-content, .card.large .card-image + .card-content { + max-height: 40%; +} + +.card.small .card-content, .card.medium .card-content, .card.large .card-content { + max-height: 100%; + overflow: hidden; +} + +.card.small .card-action, .card.medium .card-action, .card.large .card-action { + position: absolute; + bottom: 0; + left: 0; + right: 0; +} + +.card.small { + height: 300px; +} + +.card.medium { + height: 400px; +} + +.card.large { + height: 500px; +} + +.card.horizontal { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; +} + +.card.horizontal.small .card-image, .card.horizontal.medium .card-image, .card.horizontal.large .card-image { + height: 100%; + max-height: none; + overflow: visible; +} + +.card.horizontal.small .card-image img, .card.horizontal.medium .card-image img, .card.horizontal.large .card-image img { + height: 100%; +} + +.card.horizontal .card-image { + max-width: 50%; +} + +.card.horizontal .card-image img { + border-radius: 2px 0 0 2px; + max-width: 100%; + width: auto; +} + +.card.horizontal .card-stacked { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + position: relative; +} + +.card.horizontal .card-stacked .card-content { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} + +.card.sticky-action .card-action { + z-index: 2; +} + +.card.sticky-action .card-reveal { + z-index: 1; + padding-bottom: 64px; +} + +.card .card-image { + position: relative; +} + +.card .card-image img { + display: block; + border-radius: 2px 2px 0 0; + position: relative; + left: 0; + right: 0; + top: 0; + bottom: 0; + width: 100%; +} + +.card .card-image .card-title { + color: #fff; + position: absolute; + bottom: 0; + left: 0; + max-width: 100%; + padding: 24px; +} + +.card .card-content { + padding: 24px; + border-radius: 0 0 2px 2px; +} + +.card .card-content p { + margin: 0; +} + +.card .card-content .card-title { + display: block; + line-height: 32px; + margin-bottom: 8px; +} + +.card .card-content .card-title i { + line-height: 32px; +} + +.card .card-action { + background-color: inherit; + border-top: 1px solid rgba(160, 160, 160, 0.2); + position: relative; + padding: 16px 24px; +} + +.card .card-action:last-child { + border-radius: 0 0 2px 2px; +} + +.card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating) { + color: #ffab40; + margin-right: 24px; + -webkit-transition: color .3s ease; + transition: color .3s ease; + text-transform: uppercase; +} + +.card .card-action a:not(.btn):not(.btn-large):not(.btn-small):not(.btn-large):not(.btn-floating):hover { + color: #ffd8a6; +} + +.card .card-reveal { + padding: 24px; + position: absolute; + background-color: #fff; + width: 100%; + overflow-y: auto; + left: 0; + top: 100%; + height: 100%; + z-index: 3; + display: none; +} + +.card .card-reveal .card-title { + cursor: pointer; + display: block; +} + +#toast-container { + display: block; + position: fixed; + z-index: 10000; +} + +@media only screen and (max-width: 600px) { + #toast-container { + min-width: 100%; + bottom: 0%; + } +} + +@media only screen and (min-width: 601px) and (max-width: 992px) { + #toast-container { + left: 5%; + bottom: 7%; + max-width: 90%; + } +} + +@media only screen and (min-width: 993px) { + #toast-container { + top: 10%; + right: 7%; + max-width: 86%; + } +} + +.toast { + border-radius: 2px; + top: 35px; + width: auto; + margin-top: 10px; + position: relative; + max-width: 100%; + height: auto; + min-height: 48px; + line-height: 1.5em; + background-color: #323232; + padding: 10px 25px; + font-size: 1.1rem; + font-weight: 300; + color: #fff; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; + cursor: default; +} + +.toast .toast-action { + color: #eeff41; + font-weight: 500; + margin-right: -25px; + margin-left: 3rem; +} + +.toast.rounded { + border-radius: 24px; +} + +@media only screen and (max-width: 600px) { + .toast { + width: 100%; + border-radius: 0; + } +} + +.tabs { + position: relative; + overflow-x: auto; + overflow-y: hidden; + height: 48px; + width: 100%; + background-color: #fff; + margin: 0 auto; + white-space: nowrap; +} + +.tabs.tabs-transparent { + background-color: transparent; +} + +.tabs.tabs-transparent .tab a, +.tabs.tabs-transparent .tab.disabled a, +.tabs.tabs-transparent .tab.disabled a:hover { + color: rgba(255, 255, 255, 0.7); +} + +.tabs.tabs-transparent .tab a:hover, +.tabs.tabs-transparent .tab a.active { + color: #fff; +} + +.tabs.tabs-transparent .indicator { + background-color: #fff; +} + +.tabs.tabs-fixed-width { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; +} + +.tabs.tabs-fixed-width .tab { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -ms-flex-positive: 1; + flex-grow: 1; +} + +.tabs .tab { + display: inline-block; + text-align: center; + line-height: 48px; + height: 48px; + padding: 0; + margin: 0; + text-transform: uppercase; +} + +.tabs .tab a { + font-weight: bold; + color: rgba(238, 110, 115, 0.7); + display: block; + width: 100%; + height: 100%; + padding: 0 24px; + font-size: 14px; + text-overflow: ellipsis; + overflow: hidden; + -webkit-transition: color .28s ease, background-color .28s ease; + transition: color .28s ease, background-color .28s ease; +} + +.tabs .tab a:focus, .tabs .tab a:focus.active { + background-color: rgba(246, 178, 181, 0.71); + outline: none; +} + +.tabs .tab a:hover, .tabs .tab a.active { + background-color: transparent; + color: #ee6e73; +} + +.tabs .tab.disabled a, +.tabs .tab.disabled a:hover { + color: rgba(238, 110, 115, 0.4); + cursor: default; +} + +.tabs .indicator { + position: absolute; + bottom: 0; + height: 4px; + background-color: #751100; + will-change: left, right; +} + +@media only screen and (max-width: 992px) { + .tabs { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + } + .tabs .tab { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -ms-flex-positive: 1; + flex-grow: 1; + } + .tabs .tab a { + padding: 0 12px; + } +} + +.material-tooltip { + padding: 10px 8px; + font-size: 1rem; + z-index: 2000; + background-color: transparent; + border-radius: 2px; + color: #fff; + min-height: 36px; + line-height: 120%; + opacity: 0; + position: absolute; + text-align: center; + max-width: calc(100% - 4px); + overflow: hidden; + left: 0; + top: 0; + pointer-events: none; + visibility: hidden; + background-color: #323232; +} + +.backdrop { + position: absolute; + opacity: 0; + height: 7px; + width: 14px; + border-radius: 0 0 50% 50%; + background-color: #323232; + z-index: -1; + -webkit-transform-origin: 50% 0%; + transform-origin: 50% 0%; + visibility: hidden; +} + +.btn, .btn-large, .btn-small, +.btn-flat { + border: none; + border-radius: 2px; + display: inline-block; + height: 36px; + line-height: 36px; + padding: 0 16px; + text-transform: uppercase; + vertical-align: middle; + -webkit-tap-highlight-color: transparent; +} + +.btn.disabled, .disabled.btn-large, .disabled.btn-small, +.btn-floating.disabled, +.btn-large.disabled, +.btn-small.disabled, +.btn-flat.disabled, +.btn:disabled, +.btn-large:disabled, +.btn-small:disabled, +.btn-floating:disabled, +.btn-large:disabled, +.btn-small:disabled, +.btn-flat:disabled, +.btn[disabled], +.btn-large[disabled], +.btn-small[disabled], +.btn-floating[disabled], +.btn-large[disabled], +.btn-small[disabled], +.btn-flat[disabled] { + pointer-events: none; + background-color: #DFDFDF !important; + -webkit-box-shadow: none; + box-shadow: none; + color: #9F9F9F !important; + cursor: default; +} + +.btn.disabled:hover, .disabled.btn-large:hover, .disabled.btn-small:hover, +.btn-floating.disabled:hover, +.btn-large.disabled:hover, +.btn-small.disabled:hover, +.btn-flat.disabled:hover, +.btn:disabled:hover, +.btn-large:disabled:hover, +.btn-small:disabled:hover, +.btn-floating:disabled:hover, +.btn-large:disabled:hover, +.btn-small:disabled:hover, +.btn-flat:disabled:hover, +.btn[disabled]:hover, +.btn-large[disabled]:hover, +.btn-small[disabled]:hover, +.btn-floating[disabled]:hover, +.btn-large[disabled]:hover, +.btn-small[disabled]:hover, +.btn-flat[disabled]:hover { + background-color: #DFDFDF !important; + color: #9F9F9F !important; +} + +.btn, .btn-large, .btn-small, +.btn-floating, +.btn-large, +.btn-small, +.btn-flat { + font-size: 14px; + outline: 0; +} + +.btn i, .btn-large i, .btn-small i, +.btn-floating i, +.btn-large i, +.btn-small i, +.btn-flat i { + font-size: 1.3rem; + line-height: inherit; +} + +.btn:focus, .btn-large:focus, .btn-small:focus, +.btn-floating:focus { + background-color: #1d7d74; +} + +.btn, .btn-large, .btn-small { + text-decoration: none; + color: #fff; + background-color: #26a69a; + text-align: center; + letter-spacing: .5px; + -webkit-transition: background-color .2s ease-out; + transition: background-color .2s ease-out; + cursor: pointer; +} + +.btn:hover, .btn-large:hover, .btn-small:hover { + background-color: #2bbbad; +} + +.btn-floating { + display: inline-block; + color: #fff; + position: relative; + overflow: hidden; + z-index: 1; + width: 40px; + height: 40px; + line-height: 40px; + padding: 0; + background-color: #26a69a; + border-radius: 50%; + -webkit-transition: background-color .3s; + transition: background-color .3s; + cursor: pointer; + vertical-align: middle; +} + +.btn-floating:hover { + background-color: #26a69a; +} + +.btn-floating:before { + border-radius: 0; +} + +.btn-floating.btn-large { + width: 56px; + height: 56px; + padding: 0; +} + +.btn-floating.btn-large.halfway-fab { + bottom: -28px; +} + +.btn-floating.btn-large i { + line-height: 56px; +} + +.btn-floating.btn-small { + width: 32.4px; + height: 32.4px; +} + +.btn-floating.btn-small.halfway-fab { + bottom: -16.2px; +} + +.btn-floating.btn-small i { + line-height: 32.4px; +} + +.btn-floating.halfway-fab { + position: absolute; + right: 24px; + bottom: -20px; +} + +.btn-floating.halfway-fab.left { + right: auto; + left: 24px; +} + +.btn-floating i { + width: inherit; + display: inline-block; + text-align: center; + color: #fff; + font-size: 1.6rem; + line-height: 40px; +} + +button.btn-floating { + border: none; +} + +.fixed-action-btn { + position: fixed; + right: 23px; + bottom: 23px; + padding-top: 15px; + margin-bottom: 0; + z-index: 997; +} + +.fixed-action-btn.active ul { + visibility: visible; +} + +.fixed-action-btn.direction-left, .fixed-action-btn.direction-right { + padding: 0 0 0 15px; +} + +.fixed-action-btn.direction-left ul, .fixed-action-btn.direction-right ul { + text-align: right; + right: 64px; + top: 50%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + height: 100%; + left: auto; + /*width 100% only goes to width of button container */ + width: 500px; +} + +.fixed-action-btn.direction-left ul li, .fixed-action-btn.direction-right ul li { + display: inline-block; + margin: 7.5px 15px 0 0; +} + +.fixed-action-btn.direction-right { + padding: 0 15px 0 0; +} + +.fixed-action-btn.direction-right ul { + text-align: left; + direction: rtl; + left: 64px; + right: auto; +} + +.fixed-action-btn.direction-right ul li { + margin: 7.5px 0 0 15px; +} + +.fixed-action-btn.direction-bottom { + padding: 0 0 15px 0; +} + +.fixed-action-btn.direction-bottom ul { + top: 64px; + bottom: auto; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: reverse; + -webkit-flex-direction: column-reverse; + -ms-flex-direction: column-reverse; + flex-direction: column-reverse; +} + +.fixed-action-btn.direction-bottom ul li { + margin: 15px 0 0 0; +} + +.fixed-action-btn.toolbar { + padding: 0; + height: 56px; +} + +.fixed-action-btn.toolbar.active > a i { + opacity: 0; +} + +.fixed-action-btn.toolbar ul { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + top: 0; + bottom: 0; + z-index: 1; +} + +.fixed-action-btn.toolbar ul li { + -webkit-box-flex: 1; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + display: inline-block; + margin: 0; + height: 100%; + -webkit-transition: none; + transition: none; +} + +.fixed-action-btn.toolbar ul li a { + display: block; + overflow: hidden; + position: relative; + width: 100%; + height: 100%; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; + color: #fff; + line-height: 56px; + z-index: 1; +} + +.fixed-action-btn.toolbar ul li a i { + line-height: inherit; +} + +.fixed-action-btn ul { + left: 0; + right: 0; + text-align: center; + position: absolute; + bottom: 64px; + margin: 0; + visibility: hidden; +} + +.fixed-action-btn ul li { + margin-bottom: 15px; +} + +.fixed-action-btn ul a.btn-floating { + opacity: 0; +} + +.fixed-action-btn .fab-backdrop { + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 40px; + height: 40px; + background-color: #26a69a; + border-radius: 50%; + -webkit-transform: scale(0); + transform: scale(0); +} + +.btn-flat { + -webkit-box-shadow: none; + box-shadow: none; + background-color: transparent; + color: #343434; + cursor: pointer; + -webkit-transition: background-color .2s; + transition: background-color .2s; +} + +.btn-flat:focus, .btn-flat:hover { + -webkit-box-shadow: none; + box-shadow: none; +} + +.btn-flat:focus { + background-color: rgba(0, 0, 0, 0.1); +} + +.btn-flat.disabled, .btn-flat.btn-flat[disabled] { + background-color: transparent !important; + color: #b3b2b2 !important; + cursor: default; +} + +.btn-large { + height: 54px; + line-height: 54px; + font-size: 15px; + padding: 0 28px; +} + +.btn-large i { + font-size: 1.6rem; +} + +.btn-small { + height: 32.4px; + line-height: 32.4px; + font-size: 13px; +} + +.btn-small i { + font-size: 1.2rem; +} + +.btn-block { + display: block; +} + +.dropdown-content { + background-color: #fff; + margin: 0; + display: none; + min-width: 100px; + overflow-y: auto; + opacity: 0; + position: absolute; + left: 0; + top: 0; + z-index: 9999; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; +} + +.dropdown-content:focus { + outline: 0; +} + +.dropdown-content li { + clear: both; + color: rgba(0, 0, 0, 0.87); + cursor: pointer; + min-height: 50px; + line-height: 1.5rem; + width: 100%; + text-align: left; +} + +.dropdown-content li:hover, .dropdown-content li.active { + background-color: #eee; +} + +.dropdown-content li:focus { + outline: none; +} + +.dropdown-content li.divider { + min-height: 0; + height: 1px; +} + +.dropdown-content li > a, .dropdown-content li > span { + font-size: 16px; + color: #26a69a; + display: block; + line-height: 22px; + padding: 14px 16px; +} + +.dropdown-content li > span > label { + top: 1px; + left: 0; + height: 18px; +} + +.dropdown-content li > a > i { + height: inherit; + line-height: inherit; + float: left; + margin: 0 24px 0 0; + width: 24px; +} + +body.keyboard-focused .dropdown-content li:focus { + background-color: #dadada; +} + +.input-field.col .dropdown-content [type="checkbox"] + label { + top: 1px; + left: 0; + height: 18px; + -webkit-transform: none; + transform: none; +} + +.dropdown-trigger { + cursor: pointer; +} + +/*! + * Waves v0.6.0 + * http://fian.my.id/Waves + * + * Copyright 2014 Alfiana E. Sibuea and other contributors + * Released under the MIT license + * https://github.com/fians/Waves/blob/master/LICENSE + */ +.waves-effect { + position: relative; + cursor: pointer; + display: inline-block; + overflow: hidden; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-tap-highlight-color: transparent; + vertical-align: middle; + z-index: 1; + -webkit-transition: .3s ease-out; + transition: .3s ease-out; +} + +.waves-effect .waves-ripple { + position: absolute; + border-radius: 50%; + width: 20px; + height: 20px; + margin-top: -10px; + margin-left: -10px; + opacity: 0; + background: rgba(0, 0, 0, 0.2); + -webkit-transition: all 0.7s ease-out; + transition: all 0.7s ease-out; + -webkit-transition-property: opacity, -webkit-transform; + transition-property: opacity, -webkit-transform; + transition-property: transform, opacity; + transition-property: transform, opacity, -webkit-transform; + -webkit-transform: scale(0); + transform: scale(0); + pointer-events: none; +} + +.waves-effect.waves-light .waves-ripple { + background-color: rgba(255, 255, 255, 0.45); +} + +.waves-effect.waves-red .waves-ripple { + background-color: rgba(244, 67, 54, 0.7); +} + +.waves-effect.waves-yellow .waves-ripple { + background-color: rgba(255, 235, 59, 0.7); +} + +.waves-effect.waves-orange .waves-ripple { + background-color: rgba(255, 152, 0, 0.7); +} + +.waves-effect.waves-purple .waves-ripple { + background-color: rgba(156, 39, 176, 0.7); +} + +.waves-effect.waves-green .waves-ripple { + background-color: rgba(76, 175, 80, 0.7); +} + +.waves-effect.waves-teal .waves-ripple { + background-color: rgba(0, 150, 136, 0.7); +} + +.waves-effect input[type="button"], .waves-effect input[type="reset"], .waves-effect input[type="submit"] { + border: 0; + font-style: normal; + font-size: inherit; + text-transform: inherit; + background: none; +} + +.waves-effect img { + position: relative; + z-index: -1; +} + +.waves-notransition { + -webkit-transition: none !important; + transition: none !important; +} + +.waves-circle { + -webkit-transform: translateZ(0); + transform: translateZ(0); + -webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%); +} + +.waves-input-wrapper { + border-radius: 0.2em; + vertical-align: bottom; +} + +.waves-input-wrapper .waves-button-input { + position: relative; + top: 0; + left: 0; + z-index: 1; +} + +.waves-circle { + text-align: center; + width: 2.5em; + height: 2.5em; + line-height: 2.5em; + border-radius: 50%; + -webkit-mask-image: none; +} + +.waves-block { + display: block; +} + +/* Firefox Bug: link not triggered */ +.waves-effect .waves-ripple { + z-index: -1; +} + +.modal { + display: none; + position: fixed; + left: 0; + right: 0; + background-color: #fafafa; + padding: 0; + max-height: 70%; + width: 55%; + margin: auto; + overflow-y: auto; + border-radius: 2px; + will-change: top, opacity; +} + +.modal:focus { + outline: none; +} + +@media only screen and (max-width: 992px) { + .modal { + width: 80%; + } +} + +.modal h1, .modal h2, .modal h3, .modal h4 { + margin-top: 0; +} + +.modal .modal-content { + padding: 24px; +} + +.modal .modal-close { + cursor: pointer; +} + +.modal .modal-footer { + border-radius: 0 0 2px 2px; + background-color: #fafafa; + padding: 4px 6px; + height: 56px; + width: 100%; + text-align: right; +} + +.modal .modal-footer .btn, .modal .modal-footer .btn-large, .modal .modal-footer .btn-small, .modal .modal-footer .btn-flat { + margin: 6px 0; +} + +.modal-overlay { + position: fixed; + z-index: 999; + top: -25%; + left: 0; + bottom: 0; + right: 0; + height: 125%; + width: 100%; + background: #000; + display: none; + will-change: opacity; +} + +.modal.modal-fixed-footer { + padding: 0; + height: 70%; +} + +.modal.modal-fixed-footer .modal-content { + position: absolute; + height: calc(100% - 56px); + max-height: 100%; + width: 100%; + overflow-y: auto; +} + +.modal.modal-fixed-footer .modal-footer { + border-top: 1px solid rgba(0, 0, 0, 0.1); + position: absolute; + bottom: 0; +} + +.modal.bottom-sheet { + top: auto; + bottom: -100%; + margin: 0; + width: 100%; + max-height: 45%; + border-radius: 0; + will-change: bottom, opacity; +} + +.collapsible { + border-top: 1px solid #ddd; + border-right: 1px solid #ddd; + border-left: 1px solid #ddd; + margin: 0.5rem 0 1rem 0; +} + +.collapsible-header { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + cursor: pointer; + -webkit-tap-highlight-color: transparent; + line-height: 1.5; + padding: 1rem; + background-color: #fff; + border-bottom: 1px solid #ddd; +} + +.collapsible-header:focus { + outline: 0; +} + +.collapsible-header i { + width: 2rem; + font-size: 1.6rem; + display: inline-block; + text-align: center; + margin-right: 1rem; +} + +.keyboard-focused .collapsible-header:focus { + background-color: #eee; +} + +.collapsible-body { + display: none; + border-bottom: 1px solid #ddd; + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 2rem; +} + +.sidenav .collapsible, +.sidenav.fixed .collapsible { + border: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.sidenav .collapsible li, +.sidenav.fixed .collapsible li { + padding: 0; +} + +.sidenav .collapsible-header, +.sidenav.fixed .collapsible-header { + background-color: transparent; + border: none; + line-height: inherit; + height: inherit; + padding: 0 16px; +} + +.sidenav .collapsible-header:hover, +.sidenav.fixed .collapsible-header:hover { + background-color: rgba(0, 0, 0, 0.05); +} + +.sidenav .collapsible-header i, +.sidenav.fixed .collapsible-header i { + line-height: inherit; +} + +.sidenav .collapsible-body, +.sidenav.fixed .collapsible-body { + border: 0; + background-color: #fff; +} + +.sidenav .collapsible-body li a, +.sidenav.fixed .collapsible-body li a { + padding: 0 23.5px 0 31px; +} + +.collapsible.popout { + border: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.collapsible.popout > li { + -webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); + margin: 0 24px; + -webkit-transition: margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94); + transition: margin 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +.collapsible.popout > li.active { + -webkit-box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15); + box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15); + margin: 16px 0; +} + +.chip { + display: inline-block; + height: 32px; + font-size: 13px; + font-weight: 500; + color: rgba(0, 0, 0, 0.6); + line-height: 32px; + padding: 0 12px; + border-radius: 16px; + background-color: #e4e4e4; + margin-bottom: 5px; + margin-right: 5px; +} + +.chip:focus { + outline: none; + background-color: #26a69a; + color: #fff; +} + +.chip > img { + float: left; + margin: 0 8px 0 -12px; + height: 32px; + width: 32px; + border-radius: 50%; +} + +.chip .close { + cursor: pointer; + float: right; + font-size: 16px; + line-height: 32px; + padding-left: 8px; +} + +.chips { + border: none; + border-bottom: 1px solid #9e9e9e; + -webkit-box-shadow: none; + box-shadow: none; + margin: 0 0 8px 0; + min-height: 45px; + outline: none; + -webkit-transition: all .3s; + transition: all .3s; +} + +.chips.focus { + border-bottom: 1px solid #26a69a; + -webkit-box-shadow: 0 1px 0 0 #26a69a; + box-shadow: 0 1px 0 0 #26a69a; +} + +.chips:hover { + cursor: text; +} + +.chips .input { + background: none; + border: 0; + color: rgba(0, 0, 0, 0.6); + display: inline-block; + font-size: 16px; + height: 3rem; + line-height: 32px; + outline: 0; + margin: 0; + padding: 0 !important; + width: 120px !important; +} + +.chips .input:focus { + border: 0 !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +.chips .autocomplete-content { + margin-top: 0; + margin-bottom: 0; +} + +.prefix ~ .chips { + margin-left: 3rem; + width: 92%; + width: calc(100% - 3rem); +} + +.chips:empty ~ label { + font-size: 0.8rem; + -webkit-transform: translateY(-140%); + transform: translateY(-140%); +} + +.materialboxed { + display: block; + cursor: -webkit-zoom-in; + cursor: zoom-in; + position: relative; + -webkit-transition: opacity .4s; + transition: opacity .4s; + -webkit-backface-visibility: hidden; +} + +.materialboxed:hover:not(.active) { + opacity: .8; +} + +.materialboxed.active { + cursor: -webkit-zoom-out; + cursor: zoom-out; +} + +#materialbox-overlay { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: #292929; + z-index: 1000; + will-change: opacity; +} + +.materialbox-caption { + position: fixed; + display: none; + color: #fff; + line-height: 50px; + bottom: 0; + left: 0; + width: 100%; + text-align: center; + padding: 0% 15%; + height: 50px; + z-index: 1000; + -webkit-font-smoothing: antialiased; +} + +select:focus { + outline: 1px solid #c9f3ef; +} + +button:focus { + outline: none; + background-color: #2ab7a9; +} + +label { + font-size: 0.8rem; + color: #9e9e9e; +} + +/* Text Inputs + Textarea + ========================================================================== */ +/* Style Placeholders */ +::-webkit-input-placeholder { + color: #d1d1d1; +} +::-moz-placeholder { + color: #d1d1d1; +} +:-ms-input-placeholder { + color: #d1d1d1; +} +::-ms-input-placeholder { + color: #d1d1d1; +} +::placeholder { + color: #d1d1d1; +} + +/* Text inputs */ +input:not([type]), +input[type=text]:not(.browser-default), +input[type=password]:not(.browser-default), +input[type=email]:not(.browser-default), +input[type=url]:not(.browser-default), +input[type=time]:not(.browser-default), +input[type=date]:not(.browser-default), +input[type=datetime]:not(.browser-default), +input[type=datetime-local]:not(.browser-default), +input[type=tel]:not(.browser-default), +input[type=number]:not(.browser-default), +input[type=search]:not(.browser-default), +textarea.materialize-textarea { + background-color: transparent; + border: none; + border-bottom: 1px solid #9e9e9e; + border-radius: 0; + outline: none; + height: 3rem; + width: 100%; + font-size: 16px; + margin: 0 0 8px 0; + padding: 0; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-box-sizing: content-box; + box-sizing: content-box; + -webkit-transition: border .3s, -webkit-box-shadow .3s; + transition: border .3s, -webkit-box-shadow .3s; + transition: box-shadow .3s, border .3s; + transition: box-shadow .3s, border .3s, -webkit-box-shadow .3s; +} + +input:not([type]):disabled, input:not([type])[readonly="readonly"], +input[type=text]:not(.browser-default):disabled, +input[type=text]:not(.browser-default)[readonly="readonly"], +input[type=password]:not(.browser-default):disabled, +input[type=password]:not(.browser-default)[readonly="readonly"], +input[type=email]:not(.browser-default):disabled, +input[type=email]:not(.browser-default)[readonly="readonly"], +input[type=url]:not(.browser-default):disabled, +input[type=url]:not(.browser-default)[readonly="readonly"], +input[type=time]:not(.browser-default):disabled, +input[type=time]:not(.browser-default)[readonly="readonly"], +input[type=date]:not(.browser-default):disabled, +input[type=date]:not(.browser-default)[readonly="readonly"], +input[type=datetime]:not(.browser-default):disabled, +input[type=datetime]:not(.browser-default)[readonly="readonly"], +input[type=datetime-local]:not(.browser-default):disabled, +input[type=datetime-local]:not(.browser-default)[readonly="readonly"], +input[type=tel]:not(.browser-default):disabled, +input[type=tel]:not(.browser-default)[readonly="readonly"], +input[type=number]:not(.browser-default):disabled, +input[type=number]:not(.browser-default)[readonly="readonly"], +input[type=search]:not(.browser-default):disabled, +input[type=search]:not(.browser-default)[readonly="readonly"], +textarea.materialize-textarea:disabled, +textarea.materialize-textarea[readonly="readonly"] { + color: rgba(0, 0, 0, 0.42); + border-bottom: 1px dotted rgba(0, 0, 0, 0.42); +} + +input:not([type]):disabled + label, +input:not([type])[readonly="readonly"] + label, +input[type=text]:not(.browser-default):disabled + label, +input[type=text]:not(.browser-default)[readonly="readonly"] + label, +input[type=password]:not(.browser-default):disabled + label, +input[type=password]:not(.browser-default)[readonly="readonly"] + label, +input[type=email]:not(.browser-default):disabled + label, +input[type=email]:not(.browser-default)[readonly="readonly"] + label, +input[type=url]:not(.browser-default):disabled + label, +input[type=url]:not(.browser-default)[readonly="readonly"] + label, +input[type=time]:not(.browser-default):disabled + label, +input[type=time]:not(.browser-default)[readonly="readonly"] + label, +input[type=date]:not(.browser-default):disabled + label, +input[type=date]:not(.browser-default)[readonly="readonly"] + label, +input[type=datetime]:not(.browser-default):disabled + label, +input[type=datetime]:not(.browser-default)[readonly="readonly"] + label, +input[type=datetime-local]:not(.browser-default):disabled + label, +input[type=datetime-local]:not(.browser-default)[readonly="readonly"] + label, +input[type=tel]:not(.browser-default):disabled + label, +input[type=tel]:not(.browser-default)[readonly="readonly"] + label, +input[type=number]:not(.browser-default):disabled + label, +input[type=number]:not(.browser-default)[readonly="readonly"] + label, +input[type=search]:not(.browser-default):disabled + label, +input[type=search]:not(.browser-default)[readonly="readonly"] + label, +textarea.materialize-textarea:disabled + label, +textarea.materialize-textarea[readonly="readonly"] + label { + color: rgba(0, 0, 0, 0.42); +} + +input:not([type]):focus:not([readonly]), +input[type=text]:not(.browser-default):focus:not([readonly]), +input[type=password]:not(.browser-default):focus:not([readonly]), +input[type=email]:not(.browser-default):focus:not([readonly]), +input[type=url]:not(.browser-default):focus:not([readonly]), +input[type=time]:not(.browser-default):focus:not([readonly]), +input[type=date]:not(.browser-default):focus:not([readonly]), +input[type=datetime]:not(.browser-default):focus:not([readonly]), +input[type=datetime-local]:not(.browser-default):focus:not([readonly]), +input[type=tel]:not(.browser-default):focus:not([readonly]), +input[type=number]:not(.browser-default):focus:not([readonly]), +input[type=search]:not(.browser-default):focus:not([readonly]), +textarea.materialize-textarea:focus:not([readonly]) { + border-bottom: 1px solid #26a69a; + -webkit-box-shadow: 0 1px 0 0 #26a69a; + box-shadow: 0 1px 0 0 #26a69a; +} + +input:not([type]):focus:not([readonly]) + label, +input[type=text]:not(.browser-default):focus:not([readonly]) + label, +input[type=password]:not(.browser-default):focus:not([readonly]) + label, +input[type=email]:not(.browser-default):focus:not([readonly]) + label, +input[type=url]:not(.browser-default):focus:not([readonly]) + label, +input[type=time]:not(.browser-default):focus:not([readonly]) + label, +input[type=date]:not(.browser-default):focus:not([readonly]) + label, +input[type=datetime]:not(.browser-default):focus:not([readonly]) + label, +input[type=datetime-local]:not(.browser-default):focus:not([readonly]) + label, +input[type=tel]:not(.browser-default):focus:not([readonly]) + label, +input[type=number]:not(.browser-default):focus:not([readonly]) + label, +input[type=search]:not(.browser-default):focus:not([readonly]) + label, +textarea.materialize-textarea:focus:not([readonly]) + label { + color: #26a69a; +} + +input:not([type]):focus.valid ~ label, +input[type=text]:not(.browser-default):focus.valid ~ label, +input[type=password]:not(.browser-default):focus.valid ~ label, +input[type=email]:not(.browser-default):focus.valid ~ label, +input[type=url]:not(.browser-default):focus.valid ~ label, +input[type=time]:not(.browser-default):focus.valid ~ label, +input[type=date]:not(.browser-default):focus.valid ~ label, +input[type=datetime]:not(.browser-default):focus.valid ~ label, +input[type=datetime-local]:not(.browser-default):focus.valid ~ label, +input[type=tel]:not(.browser-default):focus.valid ~ label, +input[type=number]:not(.browser-default):focus.valid ~ label, +input[type=search]:not(.browser-default):focus.valid ~ label, +textarea.materialize-textarea:focus.valid ~ label { + color: #4CAF50; +} + +input:not([type]):focus.invalid ~ label, +input[type=text]:not(.browser-default):focus.invalid ~ label, +input[type=password]:not(.browser-default):focus.invalid ~ label, +input[type=email]:not(.browser-default):focus.invalid ~ label, +input[type=url]:not(.browser-default):focus.invalid ~ label, +input[type=time]:not(.browser-default):focus.invalid ~ label, +input[type=date]:not(.browser-default):focus.invalid ~ label, +input[type=datetime]:not(.browser-default):focus.invalid ~ label, +input[type=datetime-local]:not(.browser-default):focus.invalid ~ label, +input[type=tel]:not(.browser-default):focus.invalid ~ label, +input[type=number]:not(.browser-default):focus.invalid ~ label, +input[type=search]:not(.browser-default):focus.invalid ~ label, +textarea.materialize-textarea:focus.invalid ~ label { + color: #F44336; +} + +input:not([type]).validate + label, +input[type=text]:not(.browser-default).validate + label, +input[type=password]:not(.browser-default).validate + label, +input[type=email]:not(.browser-default).validate + label, +input[type=url]:not(.browser-default).validate + label, +input[type=time]:not(.browser-default).validate + label, +input[type=date]:not(.browser-default).validate + label, +input[type=datetime]:not(.browser-default).validate + label, +input[type=datetime-local]:not(.browser-default).validate + label, +input[type=tel]:not(.browser-default).validate + label, +input[type=number]:not(.browser-default).validate + label, +input[type=search]:not(.browser-default).validate + label, +textarea.materialize-textarea.validate + label { + width: 100%; +} + +/* Validation Sass Placeholders */ +input.valid:not([type]), input.valid:not([type]):focus, +input.valid[type=text]:not(.browser-default), +input.valid[type=text]:not(.browser-default):focus, +input.valid[type=password]:not(.browser-default), +input.valid[type=password]:not(.browser-default):focus, +input.valid[type=email]:not(.browser-default), +input.valid[type=email]:not(.browser-default):focus, +input.valid[type=url]:not(.browser-default), +input.valid[type=url]:not(.browser-default):focus, +input.valid[type=time]:not(.browser-default), +input.valid[type=time]:not(.browser-default):focus, +input.valid[type=date]:not(.browser-default), +input.valid[type=date]:not(.browser-default):focus, +input.valid[type=datetime]:not(.browser-default), +input.valid[type=datetime]:not(.browser-default):focus, +input.valid[type=datetime-local]:not(.browser-default), +input.valid[type=datetime-local]:not(.browser-default):focus, +input.valid[type=tel]:not(.browser-default), +input.valid[type=tel]:not(.browser-default):focus, +input.valid[type=number]:not(.browser-default), +input.valid[type=number]:not(.browser-default):focus, +input.valid[type=search]:not(.browser-default), +input.valid[type=search]:not(.browser-default):focus, +textarea.materialize-textarea.valid, +textarea.materialize-textarea.valid:focus, .select-wrapper.valid > input.select-dropdown { + border-bottom: 1px solid #4CAF50; + -webkit-box-shadow: 0 1px 0 0 #4CAF50; + box-shadow: 0 1px 0 0 #4CAF50; +} + +input.invalid:not([type]), input.invalid:not([type]):focus, +input.invalid[type=text]:not(.browser-default), +input.invalid[type=text]:not(.browser-default):focus, +input.invalid[type=password]:not(.browser-default), +input.invalid[type=password]:not(.browser-default):focus, +input.invalid[type=email]:not(.browser-default), +input.invalid[type=email]:not(.browser-default):focus, +input.invalid[type=url]:not(.browser-default), +input.invalid[type=url]:not(.browser-default):focus, +input.invalid[type=time]:not(.browser-default), +input.invalid[type=time]:not(.browser-default):focus, +input.invalid[type=date]:not(.browser-default), +input.invalid[type=date]:not(.browser-default):focus, +input.invalid[type=datetime]:not(.browser-default), +input.invalid[type=datetime]:not(.browser-default):focus, +input.invalid[type=datetime-local]:not(.browser-default), +input.invalid[type=datetime-local]:not(.browser-default):focus, +input.invalid[type=tel]:not(.browser-default), +input.invalid[type=tel]:not(.browser-default):focus, +input.invalid[type=number]:not(.browser-default), +input.invalid[type=number]:not(.browser-default):focus, +input.invalid[type=search]:not(.browser-default), +input.invalid[type=search]:not(.browser-default):focus, +textarea.materialize-textarea.invalid, +textarea.materialize-textarea.invalid:focus, .select-wrapper.invalid > input.select-dropdown, +.select-wrapper.invalid > input.select-dropdown:focus { + border-bottom: 1px solid #F44336; + -webkit-box-shadow: 0 1px 0 0 #F44336; + box-shadow: 0 1px 0 0 #F44336; +} + +input:not([type]).valid ~ .helper-text[data-success], +input:not([type]):focus.valid ~ .helper-text[data-success], +input:not([type]).invalid ~ .helper-text[data-error], +input:not([type]):focus.invalid ~ .helper-text[data-error], +input[type=text]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=text]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=text]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=text]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=password]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=password]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=password]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=password]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=email]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=email]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=email]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=email]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=url]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=url]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=url]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=url]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=time]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=time]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=time]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=time]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=date]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=date]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=date]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=date]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=datetime]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=datetime]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=datetime]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=datetime]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=datetime-local]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=datetime-local]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=datetime-local]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=datetime-local]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=tel]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=tel]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=tel]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=tel]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=number]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=number]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=number]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=number]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +input[type=search]:not(.browser-default).valid ~ .helper-text[data-success], +input[type=search]:not(.browser-default):focus.valid ~ .helper-text[data-success], +input[type=search]:not(.browser-default).invalid ~ .helper-text[data-error], +input[type=search]:not(.browser-default):focus.invalid ~ .helper-text[data-error], +textarea.materialize-textarea.valid ~ .helper-text[data-success], +textarea.materialize-textarea:focus.valid ~ .helper-text[data-success], +textarea.materialize-textarea.invalid ~ .helper-text[data-error], +textarea.materialize-textarea:focus.invalid ~ .helper-text[data-error], .select-wrapper.valid .helper-text[data-success], +.select-wrapper.invalid ~ .helper-text[data-error] { + color: transparent; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + pointer-events: none; +} + +input:not([type]).valid ~ .helper-text:after, +input:not([type]):focus.valid ~ .helper-text:after, +input[type=text]:not(.browser-default).valid ~ .helper-text:after, +input[type=text]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=password]:not(.browser-default).valid ~ .helper-text:after, +input[type=password]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=email]:not(.browser-default).valid ~ .helper-text:after, +input[type=email]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=url]:not(.browser-default).valid ~ .helper-text:after, +input[type=url]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=time]:not(.browser-default).valid ~ .helper-text:after, +input[type=time]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=date]:not(.browser-default).valid ~ .helper-text:after, +input[type=date]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=datetime]:not(.browser-default).valid ~ .helper-text:after, +input[type=datetime]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=datetime-local]:not(.browser-default).valid ~ .helper-text:after, +input[type=datetime-local]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=tel]:not(.browser-default).valid ~ .helper-text:after, +input[type=tel]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=number]:not(.browser-default).valid ~ .helper-text:after, +input[type=number]:not(.browser-default):focus.valid ~ .helper-text:after, +input[type=search]:not(.browser-default).valid ~ .helper-text:after, +input[type=search]:not(.browser-default):focus.valid ~ .helper-text:after, +textarea.materialize-textarea.valid ~ .helper-text:after, +textarea.materialize-textarea:focus.valid ~ .helper-text:after, .select-wrapper.valid ~ .helper-text:after { + content: attr(data-success); + color: #4CAF50; +} + +input:not([type]).invalid ~ .helper-text:after, +input:not([type]):focus.invalid ~ .helper-text:after, +input[type=text]:not(.browser-default).invalid ~ .helper-text:after, +input[type=text]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=password]:not(.browser-default).invalid ~ .helper-text:after, +input[type=password]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=email]:not(.browser-default).invalid ~ .helper-text:after, +input[type=email]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=url]:not(.browser-default).invalid ~ .helper-text:after, +input[type=url]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=time]:not(.browser-default).invalid ~ .helper-text:after, +input[type=time]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=date]:not(.browser-default).invalid ~ .helper-text:after, +input[type=date]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=datetime]:not(.browser-default).invalid ~ .helper-text:after, +input[type=datetime]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=datetime-local]:not(.browser-default).invalid ~ .helper-text:after, +input[type=datetime-local]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=tel]:not(.browser-default).invalid ~ .helper-text:after, +input[type=tel]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=number]:not(.browser-default).invalid ~ .helper-text:after, +input[type=number]:not(.browser-default):focus.invalid ~ .helper-text:after, +input[type=search]:not(.browser-default).invalid ~ .helper-text:after, +input[type=search]:not(.browser-default):focus.invalid ~ .helper-text:after, +textarea.materialize-textarea.invalid ~ .helper-text:after, +textarea.materialize-textarea:focus.invalid ~ .helper-text:after, .select-wrapper.invalid ~ .helper-text:after { + content: attr(data-error); + color: #F44336; +} + +input:not([type]) + label:after, +input[type=text]:not(.browser-default) + label:after, +input[type=password]:not(.browser-default) + label:after, +input[type=email]:not(.browser-default) + label:after, +input[type=url]:not(.browser-default) + label:after, +input[type=time]:not(.browser-default) + label:after, +input[type=date]:not(.browser-default) + label:after, +input[type=datetime]:not(.browser-default) + label:after, +input[type=datetime-local]:not(.browser-default) + label:after, +input[type=tel]:not(.browser-default) + label:after, +input[type=number]:not(.browser-default) + label:after, +input[type=search]:not(.browser-default) + label:after, +textarea.materialize-textarea + label:after, .select-wrapper + label:after { + display: block; + content: ""; + position: absolute; + top: 100%; + left: 0; + opacity: 0; + -webkit-transition: .2s opacity ease-out, .2s color ease-out; + transition: .2s opacity ease-out, .2s color ease-out; +} + +.input-field { + position: relative; + margin-top: 1rem; + margin-bottom: 1rem; +} + +.input-field.inline { + display: inline-block; + vertical-align: middle; + margin-left: 5px; +} + +.input-field.inline input, +.input-field.inline .select-dropdown { + margin-bottom: 1rem; +} + +.input-field.col label { + left: 0.75rem; +} + +.input-field.col .prefix ~ label, +.input-field.col .prefix ~ .validate ~ label { + width: calc(100% - 3rem - 1.5rem); +} + +.input-field > label { + color: #9e9e9e; + position: absolute; + top: 0; + left: 0; + font-size: 1rem; + cursor: text; + -webkit-transition: color .2s ease-out, -webkit-transform .2s ease-out; + transition: color .2s ease-out, -webkit-transform .2s ease-out; + transition: transform .2s ease-out, color .2s ease-out; + transition: transform .2s ease-out, color .2s ease-out, -webkit-transform .2s ease-out; + -webkit-transform-origin: 0% 100%; + transform-origin: 0% 100%; + text-align: initial; + -webkit-transform: translateY(12px); + transform: translateY(12px); +} + +.input-field > label:not(.label-icon).active { + -webkit-transform: translateY(-14px) scale(0.8); + transform: translateY(-14px) scale(0.8); + -webkit-transform-origin: 0 0; + transform-origin: 0 0; +} + +.input-field > input[type]:-webkit-autofill:not(.browser-default):not([type="search"]) + label, +.input-field > input[type=date]:not(.browser-default) + label, +.input-field > input[type=time]:not(.browser-default) + label { + -webkit-transform: translateY(-14px) scale(0.8); + transform: translateY(-14px) scale(0.8); + -webkit-transform-origin: 0 0; + transform-origin: 0 0; +} + +.input-field .helper-text { + position: relative; + min-height: 18px; + display: block; + font-size: 12px; + color: rgba(0, 0, 0, 0.54); +} + +.input-field .helper-text::after { + opacity: 1; + position: absolute; + top: 0; + left: 0; +} + +.input-field .prefix { + position: absolute; + width: 3rem; + font-size: 2rem; + -webkit-transition: color .2s; + transition: color .2s; + top: 0.5rem; +} + +.input-field .prefix.active { + color: #26a69a; +} + +.input-field .prefix ~ input, +.input-field .prefix ~ textarea, +.input-field .prefix ~ label, +.input-field .prefix ~ .validate ~ label, +.input-field .prefix ~ .helper-text, +.input-field .prefix ~ .autocomplete-content { + margin-left: 3rem; + width: 92%; + width: calc(100% - 3rem); +} + +.input-field .prefix ~ label { + margin-left: 3rem; +} + +@media only screen and (max-width: 992px) { + .input-field .prefix ~ input { + width: 86%; + width: calc(100% - 3rem); + } +} + +@media only screen and (max-width: 600px) { + .input-field .prefix ~ input { + width: 80%; + width: calc(100% - 3rem); + } +} + +/* Search Field */ +.input-field input[type=search] { + display: block; + line-height: inherit; + -webkit-transition: .3s background-color; + transition: .3s background-color; +} + +.nav-wrapper .input-field input[type=search] { + height: inherit; + padding-left: 4rem; + width: calc(100% - 4rem); + border: 0; + -webkit-box-shadow: none; + box-shadow: none; +} + +.input-field input[type=search]:focus:not(.browser-default) { + background-color: #fff; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + color: #444; +} + +.input-field input[type=search]:focus:not(.browser-default) + label i, +.input-field input[type=search]:focus:not(.browser-default) ~ .mdi-navigation-close, +.input-field input[type=search]:focus:not(.browser-default) ~ .material-icons { + color: #444; +} + +.input-field input[type=search] + .label-icon { + -webkit-transform: none; + transform: none; + left: 1rem; +} + +.input-field input[type=search] ~ .mdi-navigation-close, +.input-field input[type=search] ~ .material-icons { + position: absolute; + top: 0; + right: 1rem; + color: transparent; + cursor: pointer; + font-size: 2rem; + -webkit-transition: .3s color; + transition: .3s color; +} + +/* Textarea */ +textarea { + width: 100%; + height: 3rem; + background-color: transparent; +} + +textarea.materialize-textarea { + line-height: normal; + overflow-y: hidden; + /* prevents scroll bar flash */ + padding: .8rem 0 .8rem 0; + /* prevents text jump on Enter keypress */ + resize: none; + min-height: 3rem; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.hiddendiv { + visibility: hidden; + white-space: pre-wrap; + word-wrap: break-word; + overflow-wrap: break-word; + /* future version of deprecated 'word-wrap' */ + padding-top: 1.2rem; + /* prevents text jump on Enter keypress */ + position: absolute; + top: 0; + z-index: -1; +} + +/* Autocomplete */ +.autocomplete-content li .highlight { + color: #444; +} + +.autocomplete-content li img { + height: 40px; + width: 40px; + margin: 5px 15px; +} + +/* Character Counter */ +.character-counter { + min-height: 18px; +} + +/* Radio Buttons + ========================================================================== */ +[type="radio"]:not(:checked), +[type="radio"]:checked { + position: absolute; + opacity: 0; + pointer-events: none; +} + +[type="radio"]:not(:checked) + span, +[type="radio"]:checked + span { + position: relative; + padding-left: 35px; + cursor: pointer; + display: inline-block; + height: 25px; + line-height: 25px; + font-size: 1rem; + -webkit-transition: .28s ease; + transition: .28s ease; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +[type="radio"] + span:before, +[type="radio"] + span:after { + content: ''; + position: absolute; + left: 0; + top: 0; + margin: 4px; + width: 16px; + height: 16px; + z-index: 0; + -webkit-transition: .28s ease; + transition: .28s ease; +} + +/* Unchecked styles */ +[type="radio"]:not(:checked) + span:before, +[type="radio"]:not(:checked) + span:after, +[type="radio"]:checked + span:before, +[type="radio"]:checked + span:after, +[type="radio"].with-gap:checked + span:before, +[type="radio"].with-gap:checked + span:after { + border-radius: 50%; +} + +[type="radio"]:not(:checked) + span:before, +[type="radio"]:not(:checked) + span:after { + border: 2px solid #5a5a5a; +} + +[type="radio"]:not(:checked) + span:after { + -webkit-transform: scale(0); + transform: scale(0); +} + +/* Checked styles */ +[type="radio"]:checked + span:before { + border: 2px solid transparent; +} + +[type="radio"]:checked + span:after, +[type="radio"].with-gap:checked + span:before, +[type="radio"].with-gap:checked + span:after { + border: 2px solid #26a69a; +} + +[type="radio"]:checked + span:after, +[type="radio"].with-gap:checked + span:after { + background-color: #26a69a; +} + +[type="radio"]:checked + span:after { + -webkit-transform: scale(1.02); + transform: scale(1.02); +} + +/* Radio With gap */ +[type="radio"].with-gap:checked + span:after { + -webkit-transform: scale(0.5); + transform: scale(0.5); +} + +/* Focused styles */ +[type="radio"].tabbed:focus + span:before { + -webkit-box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); +} + +/* Disabled Radio With gap */ +[type="radio"].with-gap:disabled:checked + span:before { + border: 2px solid rgba(0, 0, 0, 0.42); +} + +[type="radio"].with-gap:disabled:checked + span:after { + border: none; + background-color: rgba(0, 0, 0, 0.42); +} + +/* Disabled style */ +[type="radio"]:disabled:not(:checked) + span:before, +[type="radio"]:disabled:checked + span:before { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.42); +} + +[type="radio"]:disabled + span { + color: rgba(0, 0, 0, 0.42); +} + +[type="radio"]:disabled:not(:checked) + span:before { + border-color: rgba(0, 0, 0, 0.42); +} + +[type="radio"]:disabled:checked + span:after { + background-color: rgba(0, 0, 0, 0.42); + border-color: #949494; +} + +/* Checkboxes + ========================================================================== */ +/* Remove default checkbox */ +[type="checkbox"]:not(:checked), +[type="checkbox"]:checked { + position: absolute; + opacity: 0; + pointer-events: none; +} + +[type="checkbox"] { + /* checkbox aspect */ +} + +[type="checkbox"] + span:not(.lever) { + position: relative; + padding-left: 35px; + cursor: pointer; + display: inline-block; + height: 25px; + line-height: 25px; + font-size: 1rem; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +[type="checkbox"] + span:not(.lever):before, +[type="checkbox"]:not(.filled-in) + span:not(.lever):after { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 18px; + height: 18px; + z-index: 0; + border: 2px solid #5a5a5a; + border-radius: 1px; + margin-top: 3px; + -webkit-transition: .2s; + transition: .2s; +} + +[type="checkbox"]:not(.filled-in) + span:not(.lever):after { + border: 0; + -webkit-transform: scale(0); + transform: scale(0); +} + +[type="checkbox"]:not(:checked):disabled + span:not(.lever):before { + border: none; + background-color: rgba(0, 0, 0, 0.42); +} + +[type="checkbox"].tabbed:focus + span:not(.lever):after { + -webkit-transform: scale(1); + transform: scale(1); + border: 0; + border-radius: 50%; + -webkit-box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1); + background-color: rgba(0, 0, 0, 0.1); +} + +[type="checkbox"]:checked + span:not(.lever):before { + top: -4px; + left: -5px; + width: 12px; + height: 22px; + border-top: 2px solid transparent; + border-left: 2px solid transparent; + border-right: 2px solid #26a69a; + border-bottom: 2px solid #26a69a; + -webkit-transform: rotate(40deg); + transform: rotate(40deg); + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform-origin: 100% 100%; + transform-origin: 100% 100%; +} + +[type="checkbox"]:checked:disabled + span:before { + border-right: 2px solid rgba(0, 0, 0, 0.42); + border-bottom: 2px solid rgba(0, 0, 0, 0.42); +} + +/* Indeterminate checkbox */ +[type="checkbox"]:indeterminate + span:not(.lever):before { + top: -11px; + left: -12px; + width: 10px; + height: 22px; + border-top: none; + border-left: none; + border-right: 2px solid #26a69a; + border-bottom: none; + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform-origin: 100% 100%; + transform-origin: 100% 100%; +} + +[type="checkbox"]:indeterminate:disabled + span:not(.lever):before { + border-right: 2px solid rgba(0, 0, 0, 0.42); + background-color: transparent; +} + +[type="checkbox"].filled-in + span:not(.lever):after { + border-radius: 2px; +} + +[type="checkbox"].filled-in + span:not(.lever):before, +[type="checkbox"].filled-in + span:not(.lever):after { + content: ''; + left: 0; + position: absolute; + /* .1s delay is for check animation */ + -webkit-transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s; + transition: border .25s, background-color .25s, width .20s .1s, height .20s .1s, top .20s .1s, left .20s .1s; + z-index: 1; +} + +[type="checkbox"].filled-in:not(:checked) + span:not(.lever):before { + width: 0; + height: 0; + border: 3px solid transparent; + left: 6px; + top: 10px; + -webkit-transform: rotateZ(37deg); + transform: rotateZ(37deg); + -webkit-transform-origin: 100% 100%; + transform-origin: 100% 100%; +} + +[type="checkbox"].filled-in:not(:checked) + span:not(.lever):after { + height: 20px; + width: 20px; + background-color: transparent; + border: 2px solid #5a5a5a; + top: 0px; + z-index: 0; +} + +[type="checkbox"].filled-in:checked + span:not(.lever):before { + top: 0; + left: 1px; + width: 8px; + height: 13px; + border-top: 2px solid transparent; + border-left: 2px solid transparent; + border-right: 2px solid #fff; + border-bottom: 2px solid #fff; + -webkit-transform: rotateZ(37deg); + transform: rotateZ(37deg); + -webkit-transform-origin: 100% 100%; + transform-origin: 100% 100%; +} + +[type="checkbox"].filled-in:checked + span:not(.lever):after { + top: 0; + width: 20px; + height: 20px; + border: 2px solid #26a69a; + background-color: #26a69a; + z-index: 0; +} + +[type="checkbox"].filled-in.tabbed:focus + span:not(.lever):after { + border-radius: 2px; + border-color: #5a5a5a; + background-color: rgba(0, 0, 0, 0.1); +} + +[type="checkbox"].filled-in.tabbed:checked:focus + span:not(.lever):after { + border-radius: 2px; + background-color: #26a69a; + border-color: #26a69a; +} + +[type="checkbox"].filled-in:disabled:not(:checked) + span:not(.lever):before { + background-color: transparent; + border: 2px solid transparent; +} + +[type="checkbox"].filled-in:disabled:not(:checked) + span:not(.lever):after { + border-color: transparent; + background-color: #949494; +} + +[type="checkbox"].filled-in:disabled:checked + span:not(.lever):before { + background-color: transparent; +} + +[type="checkbox"].filled-in:disabled:checked + span:not(.lever):after { + background-color: #949494; + border-color: #949494; +} + +/* Switch + ========================================================================== */ +.switch, +.switch * { + -webkit-tap-highlight-color: transparent; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.switch label { + cursor: pointer; +} + +.switch label input[type=checkbox] { + opacity: 0; + width: 0; + height: 0; +} + +.switch label input[type=checkbox]:checked + .lever { + background-color: #84c7c1; +} + +.switch label input[type=checkbox]:checked + .lever:before, .switch label input[type=checkbox]:checked + .lever:after { + left: 18px; +} + +.switch label input[type=checkbox]:checked + .lever:after { + background-color: #26a69a; +} + +.switch label .lever { + content: ""; + display: inline-block; + position: relative; + width: 36px; + height: 14px; + background-color: rgba(0, 0, 0, 0.38); + border-radius: 15px; + margin-right: 10px; + -webkit-transition: background 0.3s ease; + transition: background 0.3s ease; + vertical-align: middle; + margin: 0 16px; +} + +.switch label .lever:before, .switch label .lever:after { + content: ""; + position: absolute; + display: inline-block; + width: 20px; + height: 20px; + border-radius: 50%; + left: 0; + top: -3px; + -webkit-transition: left 0.3s ease, background .3s ease, -webkit-box-shadow 0.1s ease, -webkit-transform .1s ease; + transition: left 0.3s ease, background .3s ease, -webkit-box-shadow 0.1s ease, -webkit-transform .1s ease; + transition: left 0.3s ease, background .3s ease, box-shadow 0.1s ease, transform .1s ease; + transition: left 0.3s ease, background .3s ease, box-shadow 0.1s ease, transform .1s ease, -webkit-box-shadow 0.1s ease, -webkit-transform .1s ease; +} + +.switch label .lever:before { + background-color: rgba(38, 166, 154, 0.15); +} + +.switch label .lever:after { + background-color: #F1F1F1; + -webkit-box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); + box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12); +} + +input[type=checkbox]:checked:not(:disabled) ~ .lever:active::before, +input[type=checkbox]:checked:not(:disabled).tabbed:focus ~ .lever::before { + -webkit-transform: scale(2.4); + transform: scale(2.4); + background-color: rgba(38, 166, 154, 0.15); +} + +input[type=checkbox]:not(:disabled) ~ .lever:active:before, +input[type=checkbox]:not(:disabled).tabbed:focus ~ .lever::before { + -webkit-transform: scale(2.4); + transform: scale(2.4); + background-color: rgba(0, 0, 0, 0.08); +} + +.switch input[type=checkbox][disabled] + .lever { + cursor: default; + background-color: rgba(0, 0, 0, 0.12); +} + +.switch label input[type=checkbox][disabled] + .lever:after, +.switch label input[type=checkbox][disabled]:checked + .lever:after { + background-color: #949494; +} + +/* Select Field + ========================================================================== */ +select { + display: none; +} + +select.browser-default { + display: block; +} + +select { + background-color: rgba(255, 255, 255, 0.9); + width: 100%; + padding: 5px; + border: 1px solid #f2f2f2; + border-radius: 2px; + height: 3rem; +} + +.select-label { + position: absolute; +} + +.select-wrapper { + position: relative; +} + +.select-wrapper.valid + label, +.select-wrapper.invalid + label { + width: 100%; + pointer-events: none; +} + +.select-wrapper input.select-dropdown { + position: relative; + cursor: pointer; + background-color: transparent; + border: none; + border-bottom: 1px solid #9e9e9e; + outline: none; + height: 3rem; + line-height: 3rem; + width: 100%; + font-size: 16px; + margin: 0 0 8px 0; + padding: 0; + display: block; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + z-index: 1; +} + +.select-wrapper input.select-dropdown:focus { + border-bottom: 1px solid #26a69a; +} + +.select-wrapper .caret { + position: absolute; + right: 0; + top: 0; + bottom: 0; + margin: auto 0; + z-index: 0; + fill: rgba(0, 0, 0, 0.87); +} + +.select-wrapper + label { + position: absolute; + top: -26px; + font-size: 0.8rem; +} + +select:disabled { + color: rgba(0, 0, 0, 0.42); +} + +.select-wrapper.disabled + label { + color: rgba(0, 0, 0, 0.42); +} + +.select-wrapper.disabled .caret { + fill: rgba(0, 0, 0, 0.42); +} + +.select-wrapper input.select-dropdown:disabled { + color: rgba(0, 0, 0, 0.42); + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.select-wrapper i { + color: rgba(0, 0, 0, 0.3); +} + +.select-dropdown li.disabled, +.select-dropdown li.disabled > span, +.select-dropdown li.optgroup { + color: rgba(0, 0, 0, 0.3); + background-color: transparent; +} + +body.keyboard-focused .select-dropdown.dropdown-content li:focus { + background-color: rgba(0, 0, 0, 0.08); +} + +.select-dropdown.dropdown-content li:hover { + background-color: rgba(0, 0, 0, 0.08); +} + +.select-dropdown.dropdown-content li.selected { + background-color: rgba(0, 0, 0, 0.03); +} + +.prefix ~ .select-wrapper { + margin-left: 3rem; + width: 92%; + width: calc(100% - 3rem); +} + +.prefix ~ label { + margin-left: 3rem; +} + +.select-dropdown li img { + height: 40px; + width: 40px; + margin: 5px 15px; + float: right; +} + +.select-dropdown li.optgroup { + border-top: 1px solid #eee; +} + +.select-dropdown li.optgroup.selected > span { + color: rgba(0, 0, 0, 0.7); +} + +.select-dropdown li.optgroup > span { + color: rgba(0, 0, 0, 0.4); +} + +.select-dropdown li.optgroup ~ li.optgroup-option { + padding-left: 1rem; +} + +/* File Input + ========================================================================== */ +.file-field { + position: relative; +} + +.file-field .file-path-wrapper { + overflow: hidden; + padding-left: 10px; +} + +.file-field input.file-path { + width: 100%; +} + +.file-field .btn, .file-field .btn-large, .file-field .btn-small { + float: left; + height: 3rem; + line-height: 3rem; +} + +.file-field span { + cursor: pointer; +} + +.file-field input[type=file] { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + width: 100%; + margin: 0; + padding: 0; + font-size: 20px; + cursor: pointer; + opacity: 0; + filter: alpha(opacity=0); +} + +.file-field input[type=file]::-webkit-file-upload-button { + display: none; +} + +/* Range + ========================================================================== */ +.range-field { + position: relative; +} + +input[type=range], +input[type=range] + .thumb { + cursor: pointer; +} + +input[type=range] { + position: relative; + background-color: transparent; + border: none; + outline: none; + width: 100%; + margin: 15px 0; + padding: 0; +} + +input[type=range]:focus { + outline: none; +} + +input[type=range] + .thumb { + position: absolute; + top: 10px; + left: 0; + border: none; + height: 0; + width: 0; + border-radius: 50%; + background-color: #26a69a; + margin-left: 7px; + -webkit-transform-origin: 50% 50%; + transform-origin: 50% 50%; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +input[type=range] + .thumb .value { + display: block; + width: 30px; + text-align: center; + color: #26a69a; + font-size: 0; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} + +input[type=range] + .thumb.active { + border-radius: 50% 50% 50% 0; +} + +input[type=range] + .thumb.active .value { + color: #fff; + margin-left: -1px; + margin-top: 8px; + font-size: 10px; +} + +input[type=range] { + -webkit-appearance: none; +} + +input[type=range]::-webkit-slider-runnable-track { + height: 3px; + background: #c2c0c2; + border: none; +} + +input[type=range]::-webkit-slider-thumb { + border: none; + height: 14px; + width: 14px; + border-radius: 50%; + background: #26a69a; + -webkit-transition: -webkit-box-shadow .3s; + transition: -webkit-box-shadow .3s; + transition: box-shadow .3s; + transition: box-shadow .3s, -webkit-box-shadow .3s; + -webkit-appearance: none; + background-color: #26a69a; + -webkit-transform-origin: 50% 50%; + transform-origin: 50% 50%; + margin: -5px 0 0 0; +} + +.keyboard-focused input[type=range]:focus:not(.active)::-webkit-slider-thumb { + -webkit-box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26); + box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26); +} + +input[type=range] { + /* fix for FF unable to apply focus style bug */ + border: 1px solid white; + /*required for proper track sizing in FF*/ +} + +input[type=range]::-moz-range-track { + height: 3px; + background: #c2c0c2; + border: none; +} + +input[type=range]::-moz-focus-inner { + border: 0; +} + +input[type=range]::-moz-range-thumb { + border: none; + height: 14px; + width: 14px; + border-radius: 50%; + background: #26a69a; + -webkit-transition: -webkit-box-shadow .3s; + transition: -webkit-box-shadow .3s; + transition: box-shadow .3s; + transition: box-shadow .3s, -webkit-box-shadow .3s; + margin-top: -5px; +} + +input[type=range]:-moz-focusring { + outline: 1px solid #fff; + outline-offset: -1px; +} + +.keyboard-focused input[type=range]:focus:not(.active)::-moz-range-thumb { + box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26); +} + +input[type=range]::-ms-track { + height: 3px; + background: transparent; + border-color: transparent; + border-width: 6px 0; + /*remove default tick marks*/ + color: transparent; +} + +input[type=range]::-ms-fill-lower { + background: #777; +} + +input[type=range]::-ms-fill-upper { + background: #ddd; +} + +input[type=range]::-ms-thumb { + border: none; + height: 14px; + width: 14px; + border-radius: 50%; + background: #26a69a; + -webkit-transition: -webkit-box-shadow .3s; + transition: -webkit-box-shadow .3s; + transition: box-shadow .3s; + transition: box-shadow .3s, -webkit-box-shadow .3s; +} + +.keyboard-focused input[type=range]:focus:not(.active)::-ms-thumb { + box-shadow: 0 0 0 10px rgba(38, 166, 154, 0.26); +} + +/*************** + Nav List +***************/ +.table-of-contents.fixed { + position: fixed; +} + +.table-of-contents li { + padding: 2px 0; +} + +.table-of-contents a { + display: inline-block; + font-weight: 300; + color: #757575; + padding-left: 16px; + height: 1.5rem; + line-height: 1.5rem; + letter-spacing: .4; + display: inline-block; +} + +.table-of-contents a:hover { + color: #a8a8a8; + padding-left: 15px; + border-left: 1px solid #ee6e73; +} + +.table-of-contents a.active { + font-weight: 500; + padding-left: 14px; + border-left: 2px solid #ee6e73; +} + +.sidenav { + position: fixed; + width: 300px; + left: 0; + top: 0; + margin: 0; + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + height: 100%; + height: calc(100% + 60px); + height: -moz-calc(100%); + padding-bottom: 60px; + background-color: #fff; + z-index: 999; + overflow-y: auto; + will-change: transform; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transform: translateX(-105%); + transform: translateX(-105%); +} + +.sidenav.right-aligned { + right: 0; + -webkit-transform: translateX(105%); + transform: translateX(105%); + left: auto; + -webkit-transform: translateX(100%); + transform: translateX(100%); +} + +.sidenav .collapsible { + margin: 0; +} + +.sidenav li { + float: none; + line-height: 48px; +} + +.sidenav li.active { + background-color: rgba(0, 0, 0, 0.05); +} + +.sidenav li > a { + color: rgba(0, 0, 0, 0.87); + display: block; + font-size: 14px; + font-weight: 500; + height: 48px; + line-height: 48px; + padding: 0 32px; +} + +.sidenav li > a:hover { + background-color: rgba(0, 0, 0, 0.05); +} + +.sidenav li > a.btn, .sidenav li > a.btn-large, .sidenav li > a.btn-small, .sidenav li > a.btn-large, .sidenav li > a.btn-flat, .sidenav li > a.btn-floating { + margin: 10px 15px; +} + +.sidenav li > a.btn, .sidenav li > a.btn-large, .sidenav li > a.btn-small, .sidenav li > a.btn-large, .sidenav li > a.btn-floating { + color: #fff; +} + +.sidenav li > a.btn-flat { + color: #343434; +} + +.sidenav li > a.btn:hover, .sidenav li > a.btn-large:hover, .sidenav li > a.btn-small:hover, .sidenav li > a.btn-large:hover { + background-color: #2bbbad; +} + +.sidenav li > a.btn-floating:hover { + background-color: #26a69a; +} + +.sidenav li > a > i, +.sidenav li > a > [class^="mdi-"], .sidenav li > a li > a > [class*="mdi-"], +.sidenav li > a > i.material-icons { + float: left; + height: 48px; + line-height: 48px; + margin: 0 32px 0 0; + width: 24px; + color: rgba(0, 0, 0, 0.54); +} + +.sidenav .divider { + margin: 8px 0 0 0; +} + +.sidenav .subheader { + cursor: initial; + pointer-events: none; + color: rgba(0, 0, 0, 0.54); + font-size: 14px; + font-weight: 500; + line-height: 48px; +} + +.sidenav .subheader:hover { + background-color: transparent; +} + +.sidenav .user-view { + position: relative; + padding: 32px 32px 0; + margin-bottom: 8px; +} + +.sidenav .user-view > a { + height: auto; + padding: 0; +} + +.sidenav .user-view > a:hover { + background-color: transparent; +} + +.sidenav .user-view .background { + overflow: hidden; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: -1; +} + +.sidenav .user-view .circle, .sidenav .user-view .name, .sidenav .user-view .email { + display: block; +} + +.sidenav .user-view .circle { + height: 64px; + width: 64px; +} + +.sidenav .user-view .name, +.sidenav .user-view .email { + font-size: 14px; + line-height: 24px; +} + +.sidenav .user-view .name { + margin-top: 16px; + font-weight: 500; +} + +.sidenav .user-view .email { + padding-bottom: 16px; + font-weight: 400; +} + +.drag-target { + height: 100%; + width: 10px; + position: fixed; + top: 0; + z-index: 998; +} + +.drag-target.right-aligned { + right: 0; +} + +.sidenav.sidenav-fixed { + left: 0; + -webkit-transform: translateX(0); + transform: translateX(0); + position: fixed; +} + +.sidenav.sidenav-fixed.right-aligned { + right: 0; + left: auto; +} + +@media only screen and (max-width: 992px) { + .sidenav.sidenav-fixed { + -webkit-transform: translateX(-105%); + transform: translateX(-105%); + } + .sidenav.sidenav-fixed.right-aligned { + -webkit-transform: translateX(105%); + transform: translateX(105%); + } + .sidenav > a { + padding: 0 16px; + } + .sidenav .user-view { + padding: 16px 16px 0; + } +} + +.sidenav .collapsible-body > ul:not(.collapsible) > li.active, +.sidenav.sidenav-fixed .collapsible-body > ul:not(.collapsible) > li.active { + background-color: #ee6e73; +} + +.sidenav .collapsible-body > ul:not(.collapsible) > li.active a, +.sidenav.sidenav-fixed .collapsible-body > ul:not(.collapsible) > li.active a { + color: #fff; +} + +.sidenav .collapsible-body { + padding: 0; +} + +.sidenav-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + opacity: 0; + height: 120vh; + background-color: rgba(0, 0, 0, 0.5); + z-index: 997; + display: none; +} + +/* + @license + Copyright (c) 2014 The Polymer Project Authors. All rights reserved. + This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt + The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt + The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt + Code distributed by Google as part of the polymer project is also + subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt + */ +/**************************/ +/* STYLES FOR THE SPINNER */ +/**************************/ +/* + * Constants: + * STROKEWIDTH = 3px + * ARCSIZE = 270 degrees (amount of circle the arc takes up) + * ARCTIME = 1333ms (time it takes to expand and contract arc) + * ARCSTARTROT = 216 degrees (how much the start location of the arc + * should rotate each time, 216 gives us a + * 5 pointed star shape (it's 360/5 * 3). + * For a 7 pointed star, we might do + * 360/7 * 3 = 154.286) + * CONTAINERWIDTH = 28px + * SHRINK_TIME = 400ms + */ +.preloader-wrapper { + display: inline-block; + position: relative; + width: 50px; + height: 50px; +} + +.preloader-wrapper.small { + width: 36px; + height: 36px; +} + +.preloader-wrapper.big { + width: 64px; + height: 64px; +} + +.preloader-wrapper.active { + /* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */ + -webkit-animation: container-rotate 1568ms linear infinite; + animation: container-rotate 1568ms linear infinite; +} + +@-webkit-keyframes container-rotate { + to { + -webkit-transform: rotate(360deg); + } +} + +@keyframes container-rotate { + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +.spinner-layer { + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + border-color: #26a69a; +} + +.spinner-blue, +.spinner-blue-only { + border-color: #4285f4; +} + +.spinner-red, +.spinner-red-only { + border-color: #db4437; +} + +.spinner-yellow, +.spinner-yellow-only { + border-color: #f4b400; +} + +.spinner-green, +.spinner-green-only { + border-color: #0f9d58; +} + +/** + * IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee): + * + * iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't + * guarantee that the animation will start _exactly_ after that value. So we avoid using + * animation-delay and instead set custom keyframes for each color (as redundant as it + * seems). + * + * We write out each animation in full (instead of separating animation-name, + * animation-duration, etc.) because under the polyfill, Safari does not recognize those + * specific properties properly, treats them as -webkit-animation, and overrides the + * other animation rules. See https://github.com/Polymer/platform/issues/53. + */ +.active .spinner-layer.spinner-blue { + /* durations: 4 * ARCTIME */ + -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.active .spinner-layer.spinner-red { + /* durations: 4 * ARCTIME */ + -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.active .spinner-layer.spinner-yellow { + /* durations: 4 * ARCTIME */ + -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.active .spinner-layer.spinner-green { + /* durations: 4 * ARCTIME */ + -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both, green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.active .spinner-layer, +.active .spinner-layer.spinner-blue-only, +.active .spinner-layer.spinner-red-only, +.active .spinner-layer.spinner-yellow-only, +.active .spinner-layer.spinner-green-only { + /* durations: 4 * ARCTIME */ + opacity: 1; + -webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +@-webkit-keyframes fill-unfill-rotate { + 12.5% { + -webkit-transform: rotate(135deg); + } + /* 0.5 * ARCSIZE */ + 25% { + -webkit-transform: rotate(270deg); + } + /* 1 * ARCSIZE */ + 37.5% { + -webkit-transform: rotate(405deg); + } + /* 1.5 * ARCSIZE */ + 50% { + -webkit-transform: rotate(540deg); + } + /* 2 * ARCSIZE */ + 62.5% { + -webkit-transform: rotate(675deg); + } + /* 2.5 * ARCSIZE */ + 75% { + -webkit-transform: rotate(810deg); + } + /* 3 * ARCSIZE */ + 87.5% { + -webkit-transform: rotate(945deg); + } + /* 3.5 * ARCSIZE */ + to { + -webkit-transform: rotate(1080deg); + } + /* 4 * ARCSIZE */ +} + +@keyframes fill-unfill-rotate { + 12.5% { + -webkit-transform: rotate(135deg); + transform: rotate(135deg); + } + /* 0.5 * ARCSIZE */ + 25% { + -webkit-transform: rotate(270deg); + transform: rotate(270deg); + } + /* 1 * ARCSIZE */ + 37.5% { + -webkit-transform: rotate(405deg); + transform: rotate(405deg); + } + /* 1.5 * ARCSIZE */ + 50% { + -webkit-transform: rotate(540deg); + transform: rotate(540deg); + } + /* 2 * ARCSIZE */ + 62.5% { + -webkit-transform: rotate(675deg); + transform: rotate(675deg); + } + /* 2.5 * ARCSIZE */ + 75% { + -webkit-transform: rotate(810deg); + transform: rotate(810deg); + } + /* 3 * ARCSIZE */ + 87.5% { + -webkit-transform: rotate(945deg); + transform: rotate(945deg); + } + /* 3.5 * ARCSIZE */ + to { + -webkit-transform: rotate(1080deg); + transform: rotate(1080deg); + } + /* 4 * ARCSIZE */ +} + +@-webkit-keyframes blue-fade-in-out { + from { + opacity: 1; + } + 25% { + opacity: 1; + } + 26% { + opacity: 0; + } + 89% { + opacity: 0; + } + 90% { + opacity: 1; + } + 100% { + opacity: 1; + } +} + +@keyframes blue-fade-in-out { + from { + opacity: 1; + } + 25% { + opacity: 1; + } + 26% { + opacity: 0; + } + 89% { + opacity: 0; + } + 90% { + opacity: 1; + } + 100% { + opacity: 1; + } +} + +@-webkit-keyframes red-fade-in-out { + from { + opacity: 0; + } + 15% { + opacity: 0; + } + 25% { + opacity: 1; + } + 50% { + opacity: 1; + } + 51% { + opacity: 0; + } +} + +@keyframes red-fade-in-out { + from { + opacity: 0; + } + 15% { + opacity: 0; + } + 25% { + opacity: 1; + } + 50% { + opacity: 1; + } + 51% { + opacity: 0; + } +} + +@-webkit-keyframes yellow-fade-in-out { + from { + opacity: 0; + } + 40% { + opacity: 0; + } + 50% { + opacity: 1; + } + 75% { + opacity: 1; + } + 76% { + opacity: 0; + } +} + +@keyframes yellow-fade-in-out { + from { + opacity: 0; + } + 40% { + opacity: 0; + } + 50% { + opacity: 1; + } + 75% { + opacity: 1; + } + 76% { + opacity: 0; + } +} + +@-webkit-keyframes green-fade-in-out { + from { + opacity: 0; + } + 65% { + opacity: 0; + } + 75% { + opacity: 1; + } + 90% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +@keyframes green-fade-in-out { + from { + opacity: 0; + } + 65% { + opacity: 0; + } + 75% { + opacity: 1; + } + 90% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +/** + * Patch the gap that appear between the two adjacent div.circle-clipper while the + * spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11). + */ +.gap-patch { + position: absolute; + top: 0; + left: 45%; + width: 10%; + height: 100%; + overflow: hidden; + border-color: inherit; +} + +.gap-patch .circle { + width: 1000%; + left: -450%; +} + +.circle-clipper { + display: inline-block; + position: relative; + width: 50%; + height: 100%; + overflow: hidden; + border-color: inherit; +} + +.circle-clipper .circle { + width: 200%; + height: 100%; + border-width: 3px; + /* STROKEWIDTH */ + border-style: solid; + border-color: inherit; + border-bottom-color: transparent !important; + border-radius: 50%; + -webkit-animation: none; + animation: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; +} + +.circle-clipper.left .circle { + left: 0; + border-right-color: transparent !important; + -webkit-transform: rotate(129deg); + transform: rotate(129deg); +} + +.circle-clipper.right .circle { + left: -100%; + border-left-color: transparent !important; + -webkit-transform: rotate(-129deg); + transform: rotate(-129deg); +} + +.active .circle-clipper.left .circle { + /* duration: ARCTIME */ + -webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +.active .circle-clipper.right .circle { + /* duration: ARCTIME */ + -webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; + animation: right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both; +} + +@-webkit-keyframes left-spin { + from { + -webkit-transform: rotate(130deg); + } + 50% { + -webkit-transform: rotate(-5deg); + } + to { + -webkit-transform: rotate(130deg); + } +} + +@keyframes left-spin { + from { + -webkit-transform: rotate(130deg); + transform: rotate(130deg); + } + 50% { + -webkit-transform: rotate(-5deg); + transform: rotate(-5deg); + } + to { + -webkit-transform: rotate(130deg); + transform: rotate(130deg); + } +} + +@-webkit-keyframes right-spin { + from { + -webkit-transform: rotate(-130deg); + } + 50% { + -webkit-transform: rotate(5deg); + } + to { + -webkit-transform: rotate(-130deg); + } +} + +@keyframes right-spin { + from { + -webkit-transform: rotate(-130deg); + transform: rotate(-130deg); + } + 50% { + -webkit-transform: rotate(5deg); + transform: rotate(5deg); + } + to { + -webkit-transform: rotate(-130deg); + transform: rotate(-130deg); + } +} + +#spinnerContainer.cooldown { + /* duration: SHRINK_TIME */ + -webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1); + animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1); +} + +@-webkit-keyframes fade-out { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +@keyframes fade-out { + from { + opacity: 1; + } + to { + opacity: 0; + } +} + +.slider { + position: relative; + height: 400px; + width: 100%; +} + +.slider.fullscreen { + height: 100%; + width: 100%; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.slider.fullscreen ul.slides { + height: 100%; +} + +.slider.fullscreen ul.indicators { + z-index: 2; + bottom: 30px; +} + +.slider .slides { + background-color: #9e9e9e; + margin: 0; + height: 400px; +} + +.slider .slides li { + opacity: 0; + position: absolute; + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: inherit; + overflow: hidden; +} + +.slider .slides li img { + height: 100%; + width: 100%; + background-size: cover; + background-position: center; +} + +.slider .slides li .caption { + color: #fff; + position: absolute; + top: 15%; + left: 15%; + width: 70%; + opacity: 0; +} + +.slider .slides li .caption p { + color: #e0e0e0; +} + +.slider .slides li.active { + z-index: 2; +} + +.slider .indicators { + position: absolute; + text-align: center; + left: 0; + right: 0; + bottom: 0; + margin: 0; +} + +.slider .indicators .indicator-item { + display: inline-block; + position: relative; + cursor: pointer; + height: 16px; + width: 16px; + margin: 0 12px; + background-color: #e0e0e0; + -webkit-transition: background-color .3s; + transition: background-color .3s; + border-radius: 50%; +} + +.slider .indicators .indicator-item.active { + background-color: #4CAF50; +} + +.carousel { + overflow: hidden; + position: relative; + width: 100%; + height: 400px; + -webkit-perspective: 500px; + perspective: 500px; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-transform-origin: 0% 50%; + transform-origin: 0% 50%; +} + +.carousel.carousel-slider { + top: 0; + left: 0; +} + +.carousel.carousel-slider .carousel-fixed-item { + position: absolute; + left: 0; + right: 0; + bottom: 20px; + z-index: 1; +} + +.carousel.carousel-slider .carousel-fixed-item.with-indicators { + bottom: 68px; +} + +.carousel.carousel-slider .carousel-item { + width: 100%; + height: 100%; + min-height: 400px; + position: absolute; + top: 0; + left: 0; +} + +.carousel.carousel-slider .carousel-item h2 { + font-size: 24px; + font-weight: 500; + line-height: 32px; +} + +.carousel.carousel-slider .carousel-item p { + font-size: 15px; +} + +.carousel .carousel-item { + visibility: hidden; + width: 200px; + height: 200px; + position: absolute; + top: 0; + left: 0; +} + +.carousel .carousel-item > img { + width: 100%; +} + +.carousel .indicators { + position: absolute; + text-align: center; + left: 0; + right: 0; + bottom: 0; + margin: 0; +} + +.carousel .indicators .indicator-item { + display: inline-block; + position: relative; + cursor: pointer; + height: 8px; + width: 8px; + margin: 24px 4px; + background-color: rgba(255, 255, 255, 0.5); + -webkit-transition: background-color .3s; + transition: background-color .3s; + border-radius: 50%; +} + +.carousel .indicators .indicator-item.active { + background-color: #fff; +} + +.carousel.scrolling .carousel-item .materialboxed, +.carousel .carousel-item:not(.active) .materialboxed { + pointer-events: none; +} + +.tap-target-wrapper { + width: 800px; + height: 800px; + position: fixed; + z-index: 1000; + visibility: hidden; + -webkit-transition: visibility 0s .3s; + transition: visibility 0s .3s; +} + +.tap-target-wrapper.open { + visibility: visible; + -webkit-transition: visibility 0s; + transition: visibility 0s; +} + +.tap-target-wrapper.open .tap-target { + -webkit-transform: scale(1); + transform: scale(1); + opacity: .95; + -webkit-transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); + transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); + transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1); + transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); +} + +.tap-target-wrapper.open .tap-target-wave::before { + -webkit-transform: scale(1); + transform: scale(1); +} + +.tap-target-wrapper.open .tap-target-wave::after { + visibility: visible; + -webkit-animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; + animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; + -webkit-transition: opacity .3s, + visibility 0s 1s, + -webkit-transform .3s; + transition: opacity .3s, + visibility 0s 1s, + -webkit-transform .3s; + transition: opacity .3s, + transform .3s, + visibility 0s 1s; + transition: opacity .3s, + transform .3s, + visibility 0s 1s, + -webkit-transform .3s; +} + +.tap-target { + position: absolute; + font-size: 1rem; + border-radius: 50%; + background-color: #ee6e73; + -webkit-box-shadow: 0 20px 20px 0 rgba(0, 0, 0, 0.14), 0 10px 50px 0 rgba(0, 0, 0, 0.12), 0 30px 10px -20px rgba(0, 0, 0, 0.2); + box-shadow: 0 20px 20px 0 rgba(0, 0, 0, 0.14), 0 10px 50px 0 rgba(0, 0, 0, 0.12), 0 30px 10px -20px rgba(0, 0, 0, 0.2); + width: 100%; + height: 100%; + opacity: 0; + -webkit-transform: scale(0); + transform: scale(0); + -webkit-transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); + transition: opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); + transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1); + transition: transform 0.3s cubic-bezier(0.42, 0, 0.58, 1), opacity 0.3s cubic-bezier(0.42, 0, 0.58, 1), -webkit-transform 0.3s cubic-bezier(0.42, 0, 0.58, 1); +} + +.tap-target-content { + position: relative; + display: table-cell; +} + +.tap-target-wave { + position: absolute; + border-radius: 50%; + z-index: 10001; +} + +.tap-target-wave::before, .tap-target-wave::after { + content: ''; + display: block; + position: absolute; + width: 100%; + height: 100%; + border-radius: 50%; + background-color: #ffffff; +} + +.tap-target-wave::before { + -webkit-transform: scale(0); + transform: scale(0); + -webkit-transition: -webkit-transform .3s; + transition: -webkit-transform .3s; + transition: transform .3s; + transition: transform .3s, -webkit-transform .3s; +} + +.tap-target-wave::after { + visibility: hidden; + -webkit-transition: opacity .3s, + visibility 0s, + -webkit-transform .3s; + transition: opacity .3s, + visibility 0s, + -webkit-transform .3s; + transition: opacity .3s, + transform .3s, + visibility 0s; + transition: opacity .3s, + transform .3s, + visibility 0s, + -webkit-transform .3s; + z-index: -1; +} + +.tap-target-origin { + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + z-index: 10002; + position: absolute !important; +} + +.tap-target-origin:not(.btn):not(.btn-large):not(.btn-small), .tap-target-origin:not(.btn):not(.btn-large):not(.btn-small):hover { + background: none; +} + +@media only screen and (max-width: 600px) { + .tap-target, .tap-target-wrapper { + width: 600px; + height: 600px; + } +} + +.pulse { + overflow: visible; + position: relative; +} + +.pulse::before { + content: ''; + display: block; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + background-color: inherit; + border-radius: inherit; + -webkit-transition: opacity .3s, -webkit-transform .3s; + transition: opacity .3s, -webkit-transform .3s; + transition: opacity .3s, transform .3s; + transition: opacity .3s, transform .3s, -webkit-transform .3s; + -webkit-animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; + animation: pulse-animation 1s cubic-bezier(0.24, 0, 0.38, 1) infinite; + z-index: -1; +} + +@-webkit-keyframes pulse-animation { + 0% { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } + 50% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } + 100% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } +} + +@keyframes pulse-animation { + 0% { + opacity: 1; + -webkit-transform: scale(1); + transform: scale(1); + } + 50% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } + 100% { + opacity: 0; + -webkit-transform: scale(1.5); + transform: scale(1.5); + } +} + +/* Modal */ +.datepicker-modal { + max-width: 325px; + min-width: 300px; + max-height: none; +} + +.datepicker-container.modal-content { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + padding: 0; +} + +.datepicker-controls { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; + width: 280px; + margin: 0 auto; +} + +.datepicker-controls .selects-container { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; +} + +.datepicker-controls .select-wrapper input { + border-bottom: none; + text-align: center; + margin: 0; +} + +.datepicker-controls .select-wrapper input:focus { + border-bottom: none; +} + +.datepicker-controls .select-wrapper .caret { + display: none; +} + +.datepicker-controls .select-year input { + width: 50px; +} + +.datepicker-controls .select-month input { + width: 70px; +} + +.month-prev, .month-next { + margin-top: 4px; + cursor: pointer; + background-color: transparent; + border: none; +} + +/* Date Display */ +.datepicker-date-display { + -webkit-box-flex: 1; + -webkit-flex: 1 auto; + -ms-flex: 1 auto; + flex: 1 auto; + background-color: #26a69a; + color: #fff; + padding: 20px 22px; + font-weight: 500; +} + +.datepicker-date-display .year-text { + display: block; + font-size: 1.5rem; + line-height: 25px; + color: rgba(255, 255, 255, 0.7); +} + +.datepicker-date-display .date-text { + display: block; + font-size: 2.8rem; + line-height: 47px; + font-weight: 500; +} + +/* Calendar */ +.datepicker-calendar-container { + -webkit-box-flex: 2.5; + -webkit-flex: 2.5 auto; + -ms-flex: 2.5 auto; + flex: 2.5 auto; +} + +.datepicker-table { + width: 280px; + font-size: 1rem; + margin: 0 auto; +} + +.datepicker-table thead { + border-bottom: none; +} + +.datepicker-table th { + padding: 10px 5px; + text-align: center; +} + +.datepicker-table tr { + border: none; +} + +.datepicker-table abbr { + text-decoration: none; + color: #999; +} + +.datepicker-table td { + border-radius: 50%; + padding: 0; +} + +.datepicker-table td.is-today { + color: #26a69a; +} + +.datepicker-table td.is-selected { + background-color: #26a69a; + color: #fff; +} + +.datepicker-table td.is-outside-current-month, .datepicker-table td.is-disabled { + color: rgba(0, 0, 0, 0.3); + pointer-events: none; +} + +.datepicker-day-button { + background-color: transparent; + border: none; + line-height: 38px; + display: block; + width: 100%; + border-radius: 50%; + padding: 0 5px; + cursor: pointer; + color: inherit; +} + +.datepicker-day-button:focus { + background-color: rgba(43, 161, 150, 0.25); +} + +/* Footer */ +.datepicker-footer { + width: 280px; + margin: 0 auto; + padding-bottom: 5px; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.datepicker-cancel, +.datepicker-clear, +.datepicker-today, +.datepicker-done { + color: #26a69a; + padding: 0 1rem; +} + +.datepicker-clear { + color: #F44336; +} + +/* Media Queries */ +@media only screen and (min-width: 601px) { + .datepicker-modal { + max-width: 625px; + } + .datepicker-container.modal-content { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + } + .datepicker-date-display { + -webkit-box-flex: 0; + -webkit-flex: 0 1 270px; + -ms-flex: 0 1 270px; + flex: 0 1 270px; + } + .datepicker-controls, + .datepicker-table, + .datepicker-footer { + width: 320px; + } + .datepicker-day-button { + line-height: 44px; + } +} + +/* Timepicker Containers */ +.timepicker-modal { + max-width: 325px; + max-height: none; +} + +.timepicker-container.modal-content { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + padding: 0; +} + +.text-primary { + color: white; +} + +/* Clock Digital Display */ +.timepicker-digital-display { + -webkit-box-flex: 1; + -webkit-flex: 1 auto; + -ms-flex: 1 auto; + flex: 1 auto; + background-color: #26a69a; + padding: 10px; + font-weight: 300; +} + +.timepicker-text-container { + font-size: 4rem; + font-weight: bold; + text-align: center; + color: rgba(255, 255, 255, 0.6); + font-weight: 400; + position: relative; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.timepicker-span-hours, +.timepicker-span-minutes, +.timepicker-span-am-pm div { + cursor: pointer; +} + +.timepicker-span-hours { + margin-right: 3px; +} + +.timepicker-span-minutes { + margin-left: 3px; +} + +.timepicker-display-am-pm { + font-size: 1.3rem; + position: absolute; + right: 1rem; + bottom: 1rem; + font-weight: 400; +} + +/* Analog Clock Display */ +.timepicker-analog-display { + -webkit-box-flex: 2.5; + -webkit-flex: 2.5 auto; + -ms-flex: 2.5 auto; + flex: 2.5 auto; +} + +.timepicker-plate { + background-color: #eee; + border-radius: 50%; + width: 270px; + height: 270px; + overflow: visible; + position: relative; + margin: auto; + margin-top: 25px; + margin-bottom: 5px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.timepicker-canvas, +.timepicker-dial { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; +} + +.timepicker-minutes { + visibility: hidden; +} + +.timepicker-tick { + border-radius: 50%; + color: rgba(0, 0, 0, 0.87); + line-height: 40px; + text-align: center; + width: 40px; + height: 40px; + position: absolute; + cursor: pointer; + font-size: 15px; +} + +.timepicker-tick.active, +.timepicker-tick:hover { + background-color: rgba(38, 166, 154, 0.25); +} + +.timepicker-dial { + -webkit-transition: opacity 350ms, -webkit-transform 350ms; + transition: opacity 350ms, -webkit-transform 350ms; + transition: transform 350ms, opacity 350ms; + transition: transform 350ms, opacity 350ms, -webkit-transform 350ms; +} + +.timepicker-dial-out { + opacity: 0; +} + +.timepicker-dial-out.timepicker-hours { + -webkit-transform: scale(1.1, 1.1); + transform: scale(1.1, 1.1); +} + +.timepicker-dial-out.timepicker-minutes { + -webkit-transform: scale(0.8, 0.8); + transform: scale(0.8, 0.8); +} + +.timepicker-canvas { + -webkit-transition: opacity 175ms; + transition: opacity 175ms; +} + +.timepicker-canvas line { + stroke: #26a69a; + stroke-width: 4; + stroke-linecap: round; +} + +.timepicker-canvas-out { + opacity: 0.25; +} + +.timepicker-canvas-bearing { + stroke: none; + fill: #26a69a; +} + +.timepicker-canvas-bg { + stroke: none; + fill: #26a69a; +} + +/* Footer */ +.timepicker-footer { + margin: 0 auto; + padding: 5px 1rem; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.timepicker-clear { + color: #F44336; +} + +.timepicker-close { + color: #26a69a; +} + +.timepicker-clear, +.timepicker-close { + padding: 0 20px; +} + +/* Media Queries */ +@media only screen and (min-width: 601px) { + .timepicker-modal { + max-width: 600px; + } + .timepicker-container.modal-content { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + } + .timepicker-text-container { + top: 32%; + } + .timepicker-display-am-pm { + position: relative; + right: auto; + bottom: auto; + text-align: center; + margin-top: 1.2rem; + } +} diff --git a/scripts/communityModules/chat/js/materialize.min.js b/scripts/communityModules/chat/js/materialize.min.js new file mode 100644 index 0000000000..7d80c9375b --- /dev/null +++ b/scripts/communityModules/chat/js/materialize.min.js @@ -0,0 +1,6 @@ +/*! + * Materialize v1.0.0 (http://materializecss.com) + * Copyright 2014-2017 Materialize + * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) + */ +var _get=function t(e,i,n){null===e&&(e=Function.prototype);var s=Object.getOwnPropertyDescriptor(e,i);if(void 0===s){var o=Object.getPrototypeOf(e);return null===o?void 0:t(o,i,n)}if("value"in s)return s.value;var a=s.get;return void 0!==a?a.call(n):void 0},_createClass=function(){function n(t,e){for(var i=0;i/,p=/^\w+$/;function v(t,e){e=e||o;var i=u.test(t)?e.getElementsByClassName(t.slice(1)):p.test(t)?e.getElementsByTagName(t):e.querySelectorAll(t);return i}function f(t){if(!i){var e=(i=o.implementation.createHTMLDocument(null)).createElement("base");e.href=o.location.href,i.head.appendChild(e)}return i.body.innerHTML=t,i.body.childNodes}function m(t){"loading"!==o.readyState?t():o.addEventListener("DOMContentLoaded",t)}function g(t,e){if(!t)return this;if(t.cash&&t!==a)return t;var i,n=t,s=0;if(d(t))n=l.test(t)?o.getElementById(t.slice(1)):c.test(t)?f(t):v(t,e);else if(h(t))return m(t),this;if(!n)return this;if(n.nodeType||n===a)this[0]=n,this.length=1;else for(i=this.length=n.length;ss.right-i||l+e.width>window.innerWidth-i)&&(n.right=!0),(ho-i||h+e.height>window.innerHeight-i)&&(n.bottom=!0),n},M.checkPossibleAlignments=function(t,e,i,n){var s={top:!0,right:!0,bottom:!0,left:!0,spaceOnTop:null,spaceOnRight:null,spaceOnBottom:null,spaceOnLeft:null},o="visible"===getComputedStyle(e).overflow,a=e.getBoundingClientRect(),r=Math.min(a.height,window.innerHeight),l=Math.min(a.width,window.innerWidth),h=t.getBoundingClientRect(),d=e.scrollLeft,u=e.scrollTop,c=i.left-d,p=i.top-u,v=i.top+h.height-u;return s.spaceOnRight=o?window.innerWidth-(h.left+i.width):l-(c+i.width),s.spaceOnRight<0&&(s.left=!1),s.spaceOnLeft=o?h.right-i.width:c-i.width+h.width,s.spaceOnLeft<0&&(s.right=!1),s.spaceOnBottom=o?window.innerHeight-(h.top+i.height+n):r-(p+i.height+n),s.spaceOnBottom<0&&(s.top=!1),s.spaceOnTop=o?h.bottom-(i.height+n):v-(i.height-n),s.spaceOnTop<0&&(s.bottom=!1),s},M.getOverflowParent=function(t){return null==t?null:t===document.body||"visible"!==getComputedStyle(t).overflow?t:M.getOverflowParent(t.parentElement)},M.getIdFromTrigger=function(t){var e=t.getAttribute("data-target");return e||(e=(e=t.getAttribute("href"))?e.slice(1):""),e},M.getDocumentScrollTop=function(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},M.getDocumentScrollLeft=function(){return window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0};var getTime=Date.now||function(){return(new Date).getTime()};M.throttle=function(i,n,s){var o=void 0,a=void 0,r=void 0,l=null,h=0;s||(s={});var d=function(){h=!1===s.leading?0:getTime(),l=null,r=i.apply(o,a),o=a=null};return function(){var t=getTime();h||!1!==s.leading||(h=t);var e=n-(t-h);return o=this,a=arguments,e<=0?(clearTimeout(l),l=null,h=t,r=i.apply(o,a),o=a=null):l||!1===s.trailing||(l=setTimeout(d,e)),r}};var $jscomp={scope:{}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(t,e,i){if(i.get||i.set)throw new TypeError("ES3 does not support getters and setters.");t!=Array.prototype&&t!=Object.prototype&&(t[e]=i.value)},$jscomp.getGlobal=function(t){return"undefined"!=typeof window&&window===t?t:"undefined"!=typeof global&&null!=global?global:t},$jscomp.global=$jscomp.getGlobal(this),$jscomp.SYMBOL_PREFIX="jscomp_symbol_",$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){},$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)},$jscomp.symbolCounter_=0,$jscomp.Symbol=function(t){return $jscomp.SYMBOL_PREFIX+(t||"")+$jscomp.symbolCounter_++},$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var t=$jscomp.global.Symbol.iterator;t||(t=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator")),"function"!=typeof Array.prototype[t]&&$jscomp.defineProperty(Array.prototype,t,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}}),$jscomp.initSymbolIterator=function(){}},$jscomp.arrayIterator=function(t){var e=0;return $jscomp.iteratorPrototype(function(){return e=k.currentTime)for(var h=0;ht&&(s.duration=e.duration),s.children.push(e)}),s.seek(0),s.reset(),s.autoplay&&s.restart(),s},s},O.random=function(t,e){return Math.floor(Math.random()*(e-t+1))+t},O}(),function(r,l){"use strict";var e={accordion:!0,onOpenStart:void 0,onOpenEnd:void 0,onCloseStart:void 0,onCloseEnd:void 0,inDuration:300,outDuration:300},t=function(t){function s(t,e){_classCallCheck(this,s);var i=_possibleConstructorReturn(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,s,t,e));(i.el.M_Collapsible=i).options=r.extend({},s.defaults,e),i.$headers=i.$el.children("li").children(".collapsible-header"),i.$headers.attr("tabindex",0),i._setupEventHandlers();var n=i.$el.children("li.active").children(".collapsible-body");return i.options.accordion?n.first().css("display","block"):n.css("display","block"),i}return _inherits(s,Component),_createClass(s,[{key:"destroy",value:function(){this._removeEventHandlers(),this.el.M_Collapsible=void 0}},{key:"_setupEventHandlers",value:function(){var e=this;this._handleCollapsibleClickBound=this._handleCollapsibleClick.bind(this),this._handleCollapsibleKeydownBound=this._handleCollapsibleKeydown.bind(this),this.el.addEventListener("click",this._handleCollapsibleClickBound),this.$headers.each(function(t){t.addEventListener("keydown",e._handleCollapsibleKeydownBound)})}},{key:"_removeEventHandlers",value:function(){var e=this;this.el.removeEventListener("click",this._handleCollapsibleClickBound),this.$headers.each(function(t){t.removeEventListener("keydown",e._handleCollapsibleKeydownBound)})}},{key:"_handleCollapsibleClick",value:function(t){var e=r(t.target).closest(".collapsible-header");if(t.target&&e.length){var i=e.closest(".collapsible");if(i[0]===this.el){var n=e.closest("li"),s=i.children("li"),o=n[0].classList.contains("active"),a=s.index(n);o?this.close(a):this.open(a)}}}},{key:"_handleCollapsibleKeydown",value:function(t){13===t.keyCode&&this._handleCollapsibleClickBound(t)}},{key:"_animateIn",value:function(t){var e=this,i=this.$el.children("li").eq(t);if(i.length){var n=i.children(".collapsible-body");l.remove(n[0]),n.css({display:"block",overflow:"hidden",height:0,paddingTop:"",paddingBottom:""});var s=n.css("padding-top"),o=n.css("padding-bottom"),a=n[0].scrollHeight;n.css({paddingTop:0,paddingBottom:0}),l({targets:n[0],height:a,paddingTop:s,paddingBottom:o,duration:this.options.inDuration,easing:"easeInOutCubic",complete:function(t){n.css({overflow:"",paddingTop:"",paddingBottom:"",height:""}),"function"==typeof e.options.onOpenEnd&&e.options.onOpenEnd.call(e,i[0])}})}}},{key:"_animateOut",value:function(t){var e=this,i=this.$el.children("li").eq(t);if(i.length){var n=i.children(".collapsible-body");l.remove(n[0]),n.css("overflow","hidden"),l({targets:n[0],height:0,paddingTop:0,paddingBottom:0,duration:this.options.outDuration,easing:"easeInOutCubic",complete:function(){n.css({height:"",overflow:"",padding:"",display:""}),"function"==typeof e.options.onCloseEnd&&e.options.onCloseEnd.call(e,i[0])}})}}},{key:"open",value:function(t){var i=this,e=this.$el.children("li").eq(t);if(e.length&&!e[0].classList.contains("active")){if("function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,e[0]),this.options.accordion){var n=this.$el.children("li");this.$el.children("li.active").each(function(t){var e=n.index(r(t));i.close(e)})}e[0].classList.add("active"),this._animateIn(t)}}},{key:"close",value:function(t){var e=this.$el.children("li").eq(t);e.length&&e[0].classList.contains("active")&&("function"==typeof this.options.onCloseStart&&this.options.onCloseStart.call(this,e[0]),e[0].classList.remove("active"),this._animateOut(t))}}],[{key:"init",value:function(t,e){return _get(s.__proto__||Object.getPrototypeOf(s),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Collapsible}},{key:"defaults",get:function(){return e}}]),s}();M.Collapsible=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"collapsible","M_Collapsible")}(cash,M.anime),function(h,i){"use strict";var e={alignment:"left",autoFocus:!0,constrainWidth:!0,container:null,coverTrigger:!0,closeOnClick:!0,hover:!1,inDuration:150,outDuration:250,onOpenStart:null,onOpenEnd:null,onCloseStart:null,onCloseEnd:null,onItemClick:null},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return i.el.M_Dropdown=i,n._dropdowns.push(i),i.id=M.getIdFromTrigger(t),i.dropdownEl=document.getElementById(i.id),i.$dropdownEl=h(i.dropdownEl),i.options=h.extend({},n.defaults,e),i.isOpen=!1,i.isScrollable=!1,i.isTouchMoving=!1,i.focusedIndex=-1,i.filterQuery=[],i.options.container?h(i.options.container).append(i.dropdownEl):i.$el.after(i.dropdownEl),i._makeDropdownFocusable(),i._resetFilterQueryBound=i._resetFilterQuery.bind(i),i._handleDocumentClickBound=i._handleDocumentClick.bind(i),i._handleDocumentTouchmoveBound=i._handleDocumentTouchmove.bind(i),i._handleDropdownClickBound=i._handleDropdownClick.bind(i),i._handleDropdownKeydownBound=i._handleDropdownKeydown.bind(i),i._handleTriggerKeydownBound=i._handleTriggerKeydown.bind(i),i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this._resetDropdownStyles(),this._removeEventHandlers(),n._dropdowns.splice(n._dropdowns.indexOf(this),1),this.el.M_Dropdown=void 0}},{key:"_setupEventHandlers",value:function(){this.el.addEventListener("keydown",this._handleTriggerKeydownBound),this.dropdownEl.addEventListener("click",this._handleDropdownClickBound),this.options.hover?(this._handleMouseEnterBound=this._handleMouseEnter.bind(this),this.el.addEventListener("mouseenter",this._handleMouseEnterBound),this._handleMouseLeaveBound=this._handleMouseLeave.bind(this),this.el.addEventListener("mouseleave",this._handleMouseLeaveBound),this.dropdownEl.addEventListener("mouseleave",this._handleMouseLeaveBound)):(this._handleClickBound=this._handleClick.bind(this),this.el.addEventListener("click",this._handleClickBound))}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("keydown",this._handleTriggerKeydownBound),this.dropdownEl.removeEventListener("click",this._handleDropdownClickBound),this.options.hover?(this.el.removeEventListener("mouseenter",this._handleMouseEnterBound),this.el.removeEventListener("mouseleave",this._handleMouseLeaveBound),this.dropdownEl.removeEventListener("mouseleave",this._handleMouseLeaveBound)):this.el.removeEventListener("click",this._handleClickBound)}},{key:"_setupTemporaryEventHandlers",value:function(){document.body.addEventListener("click",this._handleDocumentClickBound,!0),document.body.addEventListener("touchend",this._handleDocumentClickBound),document.body.addEventListener("touchmove",this._handleDocumentTouchmoveBound),this.dropdownEl.addEventListener("keydown",this._handleDropdownKeydownBound)}},{key:"_removeTemporaryEventHandlers",value:function(){document.body.removeEventListener("click",this._handleDocumentClickBound,!0),document.body.removeEventListener("touchend",this._handleDocumentClickBound),document.body.removeEventListener("touchmove",this._handleDocumentTouchmoveBound),this.dropdownEl.removeEventListener("keydown",this._handleDropdownKeydownBound)}},{key:"_handleClick",value:function(t){t.preventDefault(),this.open()}},{key:"_handleMouseEnter",value:function(){this.open()}},{key:"_handleMouseLeave",value:function(t){var e=t.toElement||t.relatedTarget,i=!!h(e).closest(".dropdown-content").length,n=!1,s=h(e).closest(".dropdown-trigger");s.length&&s[0].M_Dropdown&&s[0].M_Dropdown.isOpen&&(n=!0),n||i||this.close()}},{key:"_handleDocumentClick",value:function(t){var e=this,i=h(t.target);this.options.closeOnClick&&i.closest(".dropdown-content").length&&!this.isTouchMoving?setTimeout(function(){e.close()},0):!i.closest(".dropdown-trigger").length&&i.closest(".dropdown-content").length||setTimeout(function(){e.close()},0),this.isTouchMoving=!1}},{key:"_handleTriggerKeydown",value:function(t){t.which!==M.keys.ARROW_DOWN&&t.which!==M.keys.ENTER||this.isOpen||(t.preventDefault(),this.open())}},{key:"_handleDocumentTouchmove",value:function(t){h(t.target).closest(".dropdown-content").length&&(this.isTouchMoving=!0)}},{key:"_handleDropdownClick",value:function(t){if("function"==typeof this.options.onItemClick){var e=h(t.target).closest("li")[0];this.options.onItemClick.call(this,e)}}},{key:"_handleDropdownKeydown",value:function(t){if(t.which===M.keys.TAB)t.preventDefault(),this.close();else if(t.which!==M.keys.ARROW_DOWN&&t.which!==M.keys.ARROW_UP||!this.isOpen)if(t.which===M.keys.ENTER&&this.isOpen){var e=this.dropdownEl.children[this.focusedIndex],i=h(e).find("a, button").first();i.length?i[0].click():e&&e.click()}else t.which===M.keys.ESC&&this.isOpen&&(t.preventDefault(),this.close());else{t.preventDefault();var n=t.which===M.keys.ARROW_DOWN?1:-1,s=this.focusedIndex,o=!1;do{if(s+=n,this.dropdownEl.children[s]&&-1!==this.dropdownEl.children[s].tabIndex){o=!0;break}}while(sl.spaceOnBottom?(h="bottom",i+=l.spaceOnTop,o-=l.spaceOnTop):i+=l.spaceOnBottom)),!l[d]){var u="left"===d?"right":"left";l[u]?d=u:l.spaceOnLeft>l.spaceOnRight?(d="right",n+=l.spaceOnLeft,s-=l.spaceOnLeft):(d="left",n+=l.spaceOnRight)}return"bottom"===h&&(o=o-e.height+(this.options.coverTrigger?t.height:0)),"right"===d&&(s=s-e.width+t.width),{x:s,y:o,verticalAlignment:h,horizontalAlignment:d,height:i,width:n}}},{key:"_animateIn",value:function(){var e=this;i.remove(this.dropdownEl),i({targets:this.dropdownEl,opacity:{value:[0,1],easing:"easeOutQuad"},scaleX:[.3,1],scaleY:[.3,1],duration:this.options.inDuration,easing:"easeOutQuint",complete:function(t){e.options.autoFocus&&e.dropdownEl.focus(),"function"==typeof e.options.onOpenEnd&&e.options.onOpenEnd.call(e,e.el)}})}},{key:"_animateOut",value:function(){var e=this;i.remove(this.dropdownEl),i({targets:this.dropdownEl,opacity:{value:0,easing:"easeOutQuint"},scaleX:.3,scaleY:.3,duration:this.options.outDuration,easing:"easeOutQuint",complete:function(t){e._resetDropdownStyles(),"function"==typeof e.options.onCloseEnd&&e.options.onCloseEnd.call(e,e.el)}})}},{key:"_placeDropdown",value:function(){var t=this.options.constrainWidth?this.el.getBoundingClientRect().width:this.dropdownEl.getBoundingClientRect().width;this.dropdownEl.style.width=t+"px";var e=this._getDropdownPosition();this.dropdownEl.style.left=e.x+"px",this.dropdownEl.style.top=e.y+"px",this.dropdownEl.style.height=e.height+"px",this.dropdownEl.style.width=e.width+"px",this.dropdownEl.style.transformOrigin=("left"===e.horizontalAlignment?"0":"100%")+" "+("top"===e.verticalAlignment?"0":"100%")}},{key:"open",value:function(){this.isOpen||(this.isOpen=!0,"function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,this.el),this._resetDropdownStyles(),this.dropdownEl.style.display="block",this._placeDropdown(),this._animateIn(),this._setupTemporaryEventHandlers())}},{key:"close",value:function(){this.isOpen&&(this.isOpen=!1,this.focusedIndex=-1,"function"==typeof this.options.onCloseStart&&this.options.onCloseStart.call(this,this.el),this._animateOut(),this._removeTemporaryEventHandlers(),this.options.autoFocus&&this.el.focus())}},{key:"recalculateDimensions",value:function(){this.isOpen&&(this.$dropdownEl.css({width:"",height:"",left:"",top:"","transform-origin":""}),this._placeDropdown())}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Dropdown}},{key:"defaults",get:function(){return e}}]),n}();t._dropdowns=[],M.Dropdown=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"dropdown","M_Dropdown")}(cash,M.anime),function(s,i){"use strict";var e={opacity:.5,inDuration:250,outDuration:250,onOpenStart:null,onOpenEnd:null,onCloseStart:null,onCloseEnd:null,preventScrolling:!0,dismissible:!0,startingTop:"4%",endingTop:"10%"},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_Modal=i).options=s.extend({},n.defaults,e),i.isOpen=!1,i.id=i.$el.attr("id"),i._openingTrigger=void 0,i.$overlay=s(''),i.el.tabIndex=0,i._nthModalOpened=0,n._count++,i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){n._count--,this._removeEventHandlers(),this.el.removeAttribute("style"),this.$overlay.remove(),this.el.M_Modal=void 0}},{key:"_setupEventHandlers",value:function(){this._handleOverlayClickBound=this._handleOverlayClick.bind(this),this._handleModalCloseClickBound=this._handleModalCloseClick.bind(this),1===n._count&&document.body.addEventListener("click",this._handleTriggerClick),this.$overlay[0].addEventListener("click",this._handleOverlayClickBound),this.el.addEventListener("click",this._handleModalCloseClickBound)}},{key:"_removeEventHandlers",value:function(){0===n._count&&document.body.removeEventListener("click",this._handleTriggerClick),this.$overlay[0].removeEventListener("click",this._handleOverlayClickBound),this.el.removeEventListener("click",this._handleModalCloseClickBound)}},{key:"_handleTriggerClick",value:function(t){var e=s(t.target).closest(".modal-trigger");if(e.length){var i=M.getIdFromTrigger(e[0]),n=document.getElementById(i).M_Modal;n&&n.open(e),t.preventDefault()}}},{key:"_handleOverlayClick",value:function(){this.options.dismissible&&this.close()}},{key:"_handleModalCloseClick",value:function(t){s(t.target).closest(".modal-close").length&&this.close()}},{key:"_handleKeydown",value:function(t){27===t.keyCode&&this.options.dismissible&&this.close()}},{key:"_handleFocus",value:function(t){this.el.contains(t.target)||this._nthModalOpened!==n._modalsOpen||this.el.focus()}},{key:"_animateIn",value:function(){var t=this;s.extend(this.el.style,{display:"block",opacity:0}),s.extend(this.$overlay[0].style,{display:"block",opacity:0}),i({targets:this.$overlay[0],opacity:this.options.opacity,duration:this.options.inDuration,easing:"easeOutQuad"});var e={targets:this.el,duration:this.options.inDuration,easing:"easeOutCubic",complete:function(){"function"==typeof t.options.onOpenEnd&&t.options.onOpenEnd.call(t,t.el,t._openingTrigger)}};this.el.classList.contains("bottom-sheet")?s.extend(e,{bottom:0,opacity:1}):s.extend(e,{top:[this.options.startingTop,this.options.endingTop],opacity:1,scaleX:[.8,1],scaleY:[.8,1]}),i(e)}},{key:"_animateOut",value:function(){var t=this;i({targets:this.$overlay[0],opacity:0,duration:this.options.outDuration,easing:"easeOutQuart"});var e={targets:this.el,duration:this.options.outDuration,easing:"easeOutCubic",complete:function(){t.el.style.display="none",t.$overlay.remove(),"function"==typeof t.options.onCloseEnd&&t.options.onCloseEnd.call(t,t.el)}};this.el.classList.contains("bottom-sheet")?s.extend(e,{bottom:"-100%",opacity:0}):s.extend(e,{top:[this.options.endingTop,this.options.startingTop],opacity:0,scaleX:.8,scaleY:.8}),i(e)}},{key:"open",value:function(t){if(!this.isOpen)return this.isOpen=!0,n._modalsOpen++,this._nthModalOpened=n._modalsOpen,this.$overlay[0].style.zIndex=1e3+2*n._modalsOpen,this.el.style.zIndex=1e3+2*n._modalsOpen+1,this._openingTrigger=t?t[0]:void 0,"function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,this.el,this._openingTrigger),this.options.preventScrolling&&(document.body.style.overflow="hidden"),this.el.classList.add("open"),this.el.insertAdjacentElement("afterend",this.$overlay[0]),this.options.dismissible&&(this._handleKeydownBound=this._handleKeydown.bind(this),this._handleFocusBound=this._handleFocus.bind(this),document.addEventListener("keydown",this._handleKeydownBound),document.addEventListener("focus",this._handleFocusBound,!0)),i.remove(this.el),i.remove(this.$overlay[0]),this._animateIn(),this.el.focus(),this}},{key:"close",value:function(){if(this.isOpen)return this.isOpen=!1,n._modalsOpen--,this._nthModalOpened=0,"function"==typeof this.options.onCloseStart&&this.options.onCloseStart.call(this,this.el),this.el.classList.remove("open"),0===n._modalsOpen&&(document.body.style.overflow=""),this.options.dismissible&&(document.removeEventListener("keydown",this._handleKeydownBound),document.removeEventListener("focus",this._handleFocusBound,!0)),i.remove(this.el),i.remove(this.$overlay[0]),this._animateOut(),this}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Modal}},{key:"defaults",get:function(){return e}}]),n}();t._modalsOpen=0,t._count=0,M.Modal=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"modal","M_Modal")}(cash,M.anime),function(o,a){"use strict";var e={inDuration:275,outDuration:200,onOpenStart:null,onOpenEnd:null,onCloseStart:null,onCloseEnd:null},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_Materialbox=i).options=o.extend({},n.defaults,e),i.overlayActive=!1,i.doneAnimating=!0,i.placeholder=o("
    ").addClass("material-placeholder"),i.originalWidth=0,i.originalHeight=0,i.originInlineStyles=i.$el.attr("style"),i.caption=i.el.getAttribute("data-caption")||"",i.$el.before(i.placeholder),i.placeholder.append(i.$el),i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this._removeEventHandlers(),this.el.M_Materialbox=void 0,o(this.placeholder).after(this.el).remove(),this.$el.removeAttr("style")}},{key:"_setupEventHandlers",value:function(){this._handleMaterialboxClickBound=this._handleMaterialboxClick.bind(this),this.el.addEventListener("click",this._handleMaterialboxClickBound)}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("click",this._handleMaterialboxClickBound)}},{key:"_handleMaterialboxClick",value:function(t){!1===this.doneAnimating||this.overlayActive&&this.doneAnimating?this.close():this.open()}},{key:"_handleWindowScroll",value:function(){this.overlayActive&&this.close()}},{key:"_handleWindowResize",value:function(){this.overlayActive&&this.close()}},{key:"_handleWindowEscape",value:function(t){27===t.keyCode&&this.doneAnimating&&this.overlayActive&&this.close()}},{key:"_makeAncestorsOverflowVisible",value:function(){this.ancestorsChanged=o();for(var t=this.placeholder[0].parentNode;null!==t&&!o(t).is(document);){var e=o(t);"visible"!==e.css("overflow")&&(e.css("overflow","visible"),void 0===this.ancestorsChanged?this.ancestorsChanged=e:this.ancestorsChanged=this.ancestorsChanged.add(e)),t=t.parentNode}}},{key:"_animateImageIn",value:function(){var t=this,e={targets:this.el,height:[this.originalHeight,this.newHeight],width:[this.originalWidth,this.newWidth],left:M.getDocumentScrollLeft()+this.windowWidth/2-this.placeholder.offset().left-this.newWidth/2,top:M.getDocumentScrollTop()+this.windowHeight/2-this.placeholder.offset().top-this.newHeight/2,duration:this.options.inDuration,easing:"easeOutQuad",complete:function(){t.doneAnimating=!0,"function"==typeof t.options.onOpenEnd&&t.options.onOpenEnd.call(t,t.el)}};this.maxWidth=this.$el.css("max-width"),this.maxHeight=this.$el.css("max-height"),"none"!==this.maxWidth&&(e.maxWidth=this.newWidth),"none"!==this.maxHeight&&(e.maxHeight=this.newHeight),a(e)}},{key:"_animateImageOut",value:function(){var t=this,e={targets:this.el,width:this.originalWidth,height:this.originalHeight,left:0,top:0,duration:this.options.outDuration,easing:"easeOutQuad",complete:function(){t.placeholder.css({height:"",width:"",position:"",top:"",left:""}),t.attrWidth&&t.$el.attr("width",t.attrWidth),t.attrHeight&&t.$el.attr("height",t.attrHeight),t.$el.removeAttr("style"),t.originInlineStyles&&t.$el.attr("style",t.originInlineStyles),t.$el.removeClass("active"),t.doneAnimating=!0,t.ancestorsChanged.length&&t.ancestorsChanged.css("overflow",""),"function"==typeof t.options.onCloseEnd&&t.options.onCloseEnd.call(t,t.el)}};a(e)}},{key:"_updateVars",value:function(){this.windowWidth=window.innerWidth,this.windowHeight=window.innerHeight,this.caption=this.el.getAttribute("data-caption")||""}},{key:"open",value:function(){var t=this;this._updateVars(),this.originalWidth=this.el.getBoundingClientRect().width,this.originalHeight=this.el.getBoundingClientRect().height,this.doneAnimating=!1,this.$el.addClass("active"),this.overlayActive=!0,"function"==typeof this.options.onOpenStart&&this.options.onOpenStart.call(this,this.el),this.placeholder.css({width:this.placeholder[0].getBoundingClientRect().width+"px",height:this.placeholder[0].getBoundingClientRect().height+"px",position:"relative",top:0,left:0}),this._makeAncestorsOverflowVisible(),this.$el.css({position:"absolute","z-index":1e3,"will-change":"left, top, width, height"}),this.attrWidth=this.$el.attr("width"),this.attrHeight=this.$el.attr("height"),this.attrWidth&&(this.$el.css("width",this.attrWidth+"px"),this.$el.removeAttr("width")),this.attrHeight&&(this.$el.css("width",this.attrHeight+"px"),this.$el.removeAttr("height")),this.$overlay=o('
    ').css({opacity:0}).one("click",function(){t.doneAnimating&&t.close()}),this.$el.before(this.$overlay);var e=this.$overlay[0].getBoundingClientRect();this.$overlay.css({width:this.windowWidth+"px",height:this.windowHeight+"px",left:-1*e.left+"px",top:-1*e.top+"px"}),a.remove(this.el),a.remove(this.$overlay[0]),a({targets:this.$overlay[0],opacity:1,duration:this.options.inDuration,easing:"easeOutQuad"}),""!==this.caption&&(this.$photocaption&&a.remove(this.$photoCaption[0]),this.$photoCaption=o('
    '),this.$photoCaption.text(this.caption),o("body").append(this.$photoCaption),this.$photoCaption.css({display:"inline"}),a({targets:this.$photoCaption[0],opacity:1,duration:this.options.inDuration,easing:"easeOutQuad"}));var i=0,n=this.originalWidth/this.windowWidth,s=this.originalHeight/this.windowHeight;this.newWidth=0,this.newHeight=0,si.options.responsiveThreshold,i.$img=i.$el.find("img").first(),i.$img.each(function(){this.complete&&s(this).trigger("load")}),i._updateParallax(),i._setupEventHandlers(),i._setupStyles(),n._parallaxes.push(i),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){n._parallaxes.splice(n._parallaxes.indexOf(this),1),this.$img[0].style.transform="",this._removeEventHandlers(),this.$el[0].M_Parallax=void 0}},{key:"_setupEventHandlers",value:function(){this._handleImageLoadBound=this._handleImageLoad.bind(this),this.$img[0].addEventListener("load",this._handleImageLoadBound),0===n._parallaxes.length&&(n._handleScrollThrottled=M.throttle(n._handleScroll,5),window.addEventListener("scroll",n._handleScrollThrottled),n._handleWindowResizeThrottled=M.throttle(n._handleWindowResize,5),window.addEventListener("resize",n._handleWindowResizeThrottled))}},{key:"_removeEventHandlers",value:function(){this.$img[0].removeEventListener("load",this._handleImageLoadBound),0===n._parallaxes.length&&(window.removeEventListener("scroll",n._handleScrollThrottled),window.removeEventListener("resize",n._handleWindowResizeThrottled))}},{key:"_setupStyles",value:function(){this.$img[0].style.opacity=1}},{key:"_handleImageLoad",value:function(){this._updateParallax()}},{key:"_updateParallax",value:function(){var t=0e.options.responsiveThreshold}}},{key:"defaults",get:function(){return e}}]),n}();t._parallaxes=[],M.Parallax=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"parallax","M_Parallax")}(cash),function(a,s){"use strict";var e={duration:300,onShow:null,swipeable:!1,responsiveThreshold:1/0},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_Tabs=i).options=a.extend({},n.defaults,e),i.$tabLinks=i.$el.children("li.tab").children("a"),i.index=0,i._setupActiveTabLink(),i.options.swipeable?i._setupSwipeableTabs():i._setupNormalTabs(),i._setTabsAndTabWidth(),i._createIndicator(),i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this._removeEventHandlers(),this._indicator.parentNode.removeChild(this._indicator),this.options.swipeable?this._teardownSwipeableTabs():this._teardownNormalTabs(),this.$el[0].M_Tabs=void 0}},{key:"_setupEventHandlers",value:function(){this._handleWindowResizeBound=this._handleWindowResize.bind(this),window.addEventListener("resize",this._handleWindowResizeBound),this._handleTabClickBound=this._handleTabClick.bind(this),this.el.addEventListener("click",this._handleTabClickBound)}},{key:"_removeEventHandlers",value:function(){window.removeEventListener("resize",this._handleWindowResizeBound),this.el.removeEventListener("click",this._handleTabClickBound)}},{key:"_handleWindowResize",value:function(){this._setTabsAndTabWidth(),0!==this.tabWidth&&0!==this.tabsWidth&&(this._indicator.style.left=this._calcLeftPos(this.$activeTabLink)+"px",this._indicator.style.right=this._calcRightPos(this.$activeTabLink)+"px")}},{key:"_handleTabClick",value:function(t){var e=this,i=a(t.target).closest("li.tab"),n=a(t.target).closest("a");if(n.length&&n.parent().hasClass("tab"))if(i.hasClass("disabled"))t.preventDefault();else if(!n.attr("target")){this.$activeTabLink.removeClass("active");var s=this.$content;this.$activeTabLink=n,this.$content=a(M.escapeHash(n[0].hash)),this.$tabLinks=this.$el.children("li.tab").children("a"),this.$activeTabLink.addClass("active");var o=this.index;this.index=Math.max(this.$tabLinks.index(n),0),this.options.swipeable?this._tabsCarousel&&this._tabsCarousel.set(this.index,function(){"function"==typeof e.options.onShow&&e.options.onShow.call(e,e.$content[0])}):this.$content.length&&(this.$content[0].style.display="block",this.$content.addClass("active"),"function"==typeof this.options.onShow&&this.options.onShow.call(this,this.$content[0]),s.length&&!s.is(this.$content)&&(s[0].style.display="none",s.removeClass("active"))),this._setTabsAndTabWidth(),this._animateIndicator(o),t.preventDefault()}}},{key:"_createIndicator",value:function(){var t=this,e=document.createElement("li");e.classList.add("indicator"),this.el.appendChild(e),this._indicator=e,setTimeout(function(){t._indicator.style.left=t._calcLeftPos(t.$activeTabLink)+"px",t._indicator.style.right=t._calcRightPos(t.$activeTabLink)+"px"},0)}},{key:"_setupActiveTabLink",value:function(){this.$activeTabLink=a(this.$tabLinks.filter('[href="'+location.hash+'"]')),0===this.$activeTabLink.length&&(this.$activeTabLink=this.$el.children("li.tab").children("a.active").first()),0===this.$activeTabLink.length&&(this.$activeTabLink=this.$el.children("li.tab").children("a").first()),this.$tabLinks.removeClass("active"),this.$activeTabLink[0].classList.add("active"),this.index=Math.max(this.$tabLinks.index(this.$activeTabLink),0),this.$activeTabLink.length&&(this.$content=a(M.escapeHash(this.$activeTabLink[0].hash)),this.$content.addClass("active"))}},{key:"_setupSwipeableTabs",value:function(){var i=this;window.innerWidth>this.options.responsiveThreshold&&(this.options.swipeable=!1);var n=a();this.$tabLinks.each(function(t){var e=a(M.escapeHash(t.hash));e.addClass("carousel-item"),n=n.add(e)});var t=a('');n.first().before(t),t.append(n),n[0].style.display="";var e=this.$activeTabLink.closest(".tab").index();this._tabsCarousel=M.Carousel.init(t[0],{fullWidth:!0,noWrap:!0,onCycleTo:function(t){var e=i.index;i.index=a(t).index(),i.$activeTabLink.removeClass("active"),i.$activeTabLink=i.$tabLinks.eq(i.index),i.$activeTabLink.addClass("active"),i._animateIndicator(e),"function"==typeof i.options.onShow&&i.options.onShow.call(i,i.$content[0])}}),this._tabsCarousel.set(e)}},{key:"_teardownSwipeableTabs",value:function(){var t=this._tabsCarousel.$el;this._tabsCarousel.destroy(),t.after(t.children()),t.remove()}},{key:"_setupNormalTabs",value:function(){this.$tabLinks.not(this.$activeTabLink).each(function(t){if(t.hash){var e=a(M.escapeHash(t.hash));e.length&&(e[0].style.display="none")}})}},{key:"_teardownNormalTabs",value:function(){this.$tabLinks.each(function(t){if(t.hash){var e=a(M.escapeHash(t.hash));e.length&&(e[0].style.display="")}})}},{key:"_setTabsAndTabWidth",value:function(){this.tabsWidth=this.$el.width(),this.tabWidth=Math.max(this.tabsWidth,this.el.scrollWidth)/this.$tabLinks.length}},{key:"_calcRightPos",value:function(t){return Math.ceil(this.tabsWidth-t.position().left-t[0].getBoundingClientRect().width)}},{key:"_calcLeftPos",value:function(t){return Math.floor(t.position().left)}},{key:"updateTabIndicator",value:function(){this._setTabsAndTabWidth(),this._animateIndicator(this.index)}},{key:"_animateIndicator",value:function(t){var e=0,i=0;0<=this.index-t?e=90:i=90;var n={targets:this._indicator,left:{value:this._calcLeftPos(this.$activeTabLink),delay:e},right:{value:this._calcRightPos(this.$activeTabLink),delay:i},duration:this.options.duration,easing:"easeOutQuad"};s.remove(this._indicator),s(n)}},{key:"select",value:function(t){var e=this.$tabLinks.filter('[href="#'+t+'"]');e.length&&e.trigger("click")}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Tabs}},{key:"defaults",get:function(){return e}}]),n}();M.Tabs=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"tabs","M_Tabs")}(cash,M.anime),function(d,e){"use strict";var i={exitDelay:200,enterDelay:0,html:null,margin:5,inDuration:250,outDuration:200,position:"bottom",transitionMovement:10},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_Tooltip=i).options=d.extend({},n.defaults,e),i.isOpen=!1,i.isHovered=!1,i.isFocused=!1,i._appendTooltipEl(),i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){d(this.tooltipEl).remove(),this._removeEventHandlers(),this.el.M_Tooltip=void 0}},{key:"_appendTooltipEl",value:function(){var t=document.createElement("div");t.classList.add("material-tooltip"),this.tooltipEl=t;var e=document.createElement("div");e.classList.add("tooltip-content"),e.innerHTML=this.options.html,t.appendChild(e),document.body.appendChild(t)}},{key:"_updateTooltipContent",value:function(){this.tooltipEl.querySelector(".tooltip-content").innerHTML=this.options.html}},{key:"_setupEventHandlers",value:function(){this._handleMouseEnterBound=this._handleMouseEnter.bind(this),this._handleMouseLeaveBound=this._handleMouseLeave.bind(this),this._handleFocusBound=this._handleFocus.bind(this),this._handleBlurBound=this._handleBlur.bind(this),this.el.addEventListener("mouseenter",this._handleMouseEnterBound),this.el.addEventListener("mouseleave",this._handleMouseLeaveBound),this.el.addEventListener("focus",this._handleFocusBound,!0),this.el.addEventListener("blur",this._handleBlurBound,!0)}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("mouseenter",this._handleMouseEnterBound),this.el.removeEventListener("mouseleave",this._handleMouseLeaveBound),this.el.removeEventListener("focus",this._handleFocusBound,!0),this.el.removeEventListener("blur",this._handleBlurBound,!0)}},{key:"open",value:function(t){this.isOpen||(t=void 0===t||void 0,this.isOpen=!0,this.options=d.extend({},this.options,this._getAttributeOptions()),this._updateTooltipContent(),this._setEnterDelayTimeout(t))}},{key:"close",value:function(){this.isOpen&&(this.isHovered=!1,this.isFocused=!1,this.isOpen=!1,this._setExitDelayTimeout())}},{key:"_setExitDelayTimeout",value:function(){var t=this;clearTimeout(this._exitDelayTimeout),this._exitDelayTimeout=setTimeout(function(){t.isHovered||t.isFocused||t._animateOut()},this.options.exitDelay)}},{key:"_setEnterDelayTimeout",value:function(t){var e=this;clearTimeout(this._enterDelayTimeout),this._enterDelayTimeout=setTimeout(function(){(e.isHovered||e.isFocused||t)&&e._animateIn()},this.options.enterDelay)}},{key:"_positionTooltip",value:function(){var t,e=this.el,i=this.tooltipEl,n=e.offsetHeight,s=e.offsetWidth,o=i.offsetHeight,a=i.offsetWidth,r=this.options.margin,l=void 0,h=void 0;this.xMovement=0,this.yMovement=0,l=e.getBoundingClientRect().top+M.getDocumentScrollTop(),h=e.getBoundingClientRect().left+M.getDocumentScrollLeft(),"top"===this.options.position?(l+=-o-r,h+=s/2-a/2,this.yMovement=-this.options.transitionMovement):"right"===this.options.position?(l+=n/2-o/2,h+=s+r,this.xMovement=this.options.transitionMovement):"left"===this.options.position?(l+=n/2-o/2,h+=-a-r,this.xMovement=-this.options.transitionMovement):(l+=n+r,h+=s/2-a/2,this.yMovement=this.options.transitionMovement),t=this._repositionWithinScreen(h,l,a,o),d(i).css({top:t.y+"px",left:t.x+"px"})}},{key:"_repositionWithinScreen",value:function(t,e,i,n){var s=M.getDocumentScrollLeft(),o=M.getDocumentScrollTop(),a=t-s,r=e-o,l={left:a,top:r,width:i,height:n},h=this.options.margin+this.options.transitionMovement,d=M.checkWithinContainer(document.body,l,h);return d.left?a=h:d.right&&(a-=a+i-window.innerWidth),d.top?r=h:d.bottom&&(r-=r+n-window.innerHeight),{x:a+s,y:r+o}}},{key:"_animateIn",value:function(){this._positionTooltip(),this.tooltipEl.style.visibility="visible",e.remove(this.tooltipEl),e({targets:this.tooltipEl,opacity:1,translateX:this.xMovement,translateY:this.yMovement,duration:this.options.inDuration,easing:"easeOutCubic"})}},{key:"_animateOut",value:function(){e.remove(this.tooltipEl),e({targets:this.tooltipEl,opacity:0,translateX:0,translateY:0,duration:this.options.outDuration,easing:"easeOutCubic"})}},{key:"_handleMouseEnter",value:function(){this.isHovered=!0,this.isFocused=!1,this.open(!1)}},{key:"_handleMouseLeave",value:function(){this.isHovered=!1,this.isFocused=!1,this.close()}},{key:"_handleFocus",value:function(){M.tabPressed&&(this.isFocused=!0,this.open(!1))}},{key:"_handleBlur",value:function(){this.isFocused=!1,this.close()}},{key:"_getAttributeOptions",value:function(){var t={},e=this.el.getAttribute("data-tooltip"),i=this.el.getAttribute("data-position");return e&&(t.html=e),i&&(t.position=i),t}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Tooltip}},{key:"defaults",get:function(){return i}}]),n}();M.Tooltip=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"tooltip","M_Tooltip")}(cash,M.anime),function(i){"use strict";var t=t||{},e=document.querySelectorAll.bind(document);function m(t){var e="";for(var i in t)t.hasOwnProperty(i)&&(e+=i+":"+t[i]+";");return e}var g={duration:750,show:function(t,e){if(2===t.button)return!1;var i=e||this,n=document.createElement("div");n.className="waves-ripple",i.appendChild(n);var s,o,a,r,l,h,d,u=(h={top:0,left:0},d=(s=i)&&s.ownerDocument,o=d.documentElement,void 0!==s.getBoundingClientRect&&(h=s.getBoundingClientRect()),a=null!==(l=r=d)&&l===l.window?r:9===r.nodeType&&r.defaultView,{top:h.top+a.pageYOffset-o.clientTop,left:h.left+a.pageXOffset-o.clientLeft}),c=t.pageY-u.top,p=t.pageX-u.left,v="scale("+i.clientWidth/100*10+")";"touches"in t&&(c=t.touches[0].pageY-u.top,p=t.touches[0].pageX-u.left),n.setAttribute("data-hold",Date.now()),n.setAttribute("data-scale",v),n.setAttribute("data-x",p),n.setAttribute("data-y",c);var f={top:c+"px",left:p+"px"};n.className=n.className+" waves-notransition",n.setAttribute("style",m(f)),n.className=n.className.replace("waves-notransition",""),f["-webkit-transform"]=v,f["-moz-transform"]=v,f["-ms-transform"]=v,f["-o-transform"]=v,f.transform=v,f.opacity="1",f["-webkit-transition-duration"]=g.duration+"ms",f["-moz-transition-duration"]=g.duration+"ms",f["-o-transition-duration"]=g.duration+"ms",f["transition-duration"]=g.duration+"ms",f["-webkit-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",f["-moz-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",f["-o-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",f["transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",n.setAttribute("style",m(f))},hide:function(t){l.touchup(t);var e=this,i=(e.clientWidth,null),n=e.getElementsByClassName("waves-ripple");if(!(0i||1"+o+""+a+""+r+""),i.length&&e.prepend(i)}},{key:"_resetCurrentElement",value:function(){this.activeIndex=-1,this.$active.removeClass("active")}},{key:"_resetAutocomplete",value:function(){h(this.container).empty(),this._resetCurrentElement(),this.oldVal=null,this.isOpen=!1,this._mousedown=!1}},{key:"selectOption",value:function(t){var e=t.text().trim();this.el.value=e,this.$el.trigger("change"),this._resetAutocomplete(),this.close(),"function"==typeof this.options.onAutocomplete&&this.options.onAutocomplete.call(this,e)}},{key:"_renderDropdown",value:function(t,i){var n=this;this._resetAutocomplete();var e=[];for(var s in t)if(t.hasOwnProperty(s)&&-1!==s.toLowerCase().indexOf(i)){if(this.count>=this.options.limit)break;var o={data:t[s],key:s};e.push(o),this.count++}if(this.options.sortFunction){e.sort(function(t,e){return n.options.sortFunction(t.key.toLowerCase(),e.key.toLowerCase(),i.toLowerCase())})}for(var a=0;a");r.data?l.append(''+r.key+""):l.append(""+r.key+""),h(this.container).append(l),this._highlight(i,l)}}},{key:"open",value:function(){var t=this.el.value.toLowerCase();this._resetAutocomplete(),t.length>=this.options.minLength&&(this.isOpen=!0,this._renderDropdown(this.options.data,t)),this.dropdown.isOpen?this.dropdown.recalculateDimensions():this.dropdown.open()}},{key:"close",value:function(){this.dropdown.close()}},{key:"updateData",value:function(t){var e=this.el.value.toLowerCase();this.options.data=t,this.isOpen&&this._renderDropdown(t,e)}}],[{key:"init",value:function(t,e){return _get(s.__proto__||Object.getPrototypeOf(s),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Autocomplete}},{key:"defaults",get:function(){return e}}]),s}();t._keydown=!1,M.Autocomplete=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"autocomplete","M_Autocomplete")}(cash),function(d){M.updateTextFields=function(){d("input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], input[type=date], input[type=time], textarea").each(function(t,e){var i=d(this);0'),d("body").append(e));var i=t.css("font-family"),n=t.css("font-size"),s=t.css("line-height"),o=t.css("padding-top"),a=t.css("padding-right"),r=t.css("padding-bottom"),l=t.css("padding-left");n&&e.css("font-size",n),i&&e.css("font-family",i),s&&e.css("line-height",s),o&&e.css("padding-top",o),a&&e.css("padding-right",a),r&&e.css("padding-bottom",r),l&&e.css("padding-left",l),t.data("original-height")||t.data("original-height",t.height()),"off"===t.attr("wrap")&&e.css("overflow-wrap","normal").css("white-space","pre"),e.text(t[0].value+"\n");var h=e.html().replace(/\n/g,"
    ");e.html(h),0'),this.$slides.each(function(t,e){var i=s('
  • ');n.$indicators.append(i[0])}),this.$el.append(this.$indicators[0]),this.$indicators=this.$indicators.children("li.indicator-item"))}},{key:"_removeIndicators",value:function(){this.$el.find("ul.indicators").remove()}},{key:"set",value:function(t){var e=this;if(t>=this.$slides.length?t=0:t<0&&(t=this.$slides.length-1),this.activeIndex!=t){this.$active=this.$slides.eq(this.activeIndex);var i=this.$active.find(".caption");this.$active.removeClass("active"),o({targets:this.$active[0],opacity:0,duration:this.options.duration,easing:"easeOutQuad",complete:function(){e.$slides.not(".active").each(function(t){o({targets:t,opacity:0,translateX:0,translateY:0,duration:0,easing:"easeOutQuad"})})}}),this._animateCaptionIn(i[0],this.options.duration),this.options.indicators&&(this.$indicators.eq(this.activeIndex).removeClass("active"),this.$indicators.eq(t).addClass("active")),o({targets:this.$slides.eq(t)[0],opacity:1,duration:this.options.duration,easing:"easeOutQuad"}),o({targets:this.$slides.eq(t).find(".caption")[0],opacity:1,translateX:0,translateY:0,duration:this.options.duration,delay:this.options.duration,easing:"easeOutQuad"}),this.$slides.eq(t).addClass("active"),this.activeIndex=t,this.start()}}},{key:"pause",value:function(){clearInterval(this.interval)}},{key:"start",value:function(){clearInterval(this.interval),this.interval=setInterval(this._handleIntervalBound,this.options.duration+this.options.interval)}},{key:"next",value:function(){var t=this.activeIndex+1;t>=this.$slides.length?t=0:t<0&&(t=this.$slides.length-1),this.set(t)}},{key:"prev",value:function(){var t=this.activeIndex-1;t>=this.$slides.length?t=0:t<0&&(t=this.$slides.length-1),this.set(t)}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Slider}},{key:"defaults",get:function(){return e}}]),n}();M.Slider=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"slider","M_Slider")}(cash,M.anime),function(n,s){n(document).on("click",".card",function(t){if(n(this).children(".card-reveal").length){var i=n(t.target).closest(".card");void 0===i.data("initialOverflow")&&i.data("initialOverflow",void 0===i.css("overflow")?"":i.css("overflow"));var e=n(this).find(".card-reveal");n(t.target).is(n(".card-reveal .card-title"))||n(t.target).is(n(".card-reveal .card-title i"))?s({targets:e[0],translateY:0,duration:225,easing:"easeInOutQuad",complete:function(t){var e=t.animatables[0].target;n(e).css({display:"none"}),i.css("overflow",i.data("initialOverflow"))}}):(n(t.target).is(n(".card .activator"))||n(t.target).is(n(".card .activator i")))&&(i.css("overflow","hidden"),e.css({display:"block"}),s({targets:e[0],translateY:"-100%",duration:300,easing:"easeInOutQuad"}))}})}(cash,M.anime),function(h){"use strict";var e={data:[],placeholder:"",secondaryPlaceholder:"",autocompleteOptions:{},limit:1/0,onChipAdd:null,onChipSelect:null,onChipDelete:null},t=function(t){function l(t,e){_classCallCheck(this,l);var i=_possibleConstructorReturn(this,(l.__proto__||Object.getPrototypeOf(l)).call(this,l,t,e));return(i.el.M_Chips=i).options=h.extend({},l.defaults,e),i.$el.addClass("chips input-field"),i.chipsData=[],i.$chips=h(),i._setupInput(),i.hasAutocomplete=0"),this.$el.append(this.$input)),this.$input.addClass("input")}},{key:"_setupLabel",value:function(){this.$label=this.$el.find("label"),this.$label.length&&this.$label.setAttribute("for",this.$input.attr("id"))}},{key:"_setPlaceholder",value:function(){void 0!==this.chipsData&&!this.chipsData.length&&this.options.placeholder?h(this.$input).prop("placeholder",this.options.placeholder):(void 0===this.chipsData||this.chipsData.length)&&this.options.secondaryPlaceholder&&h(this.$input).prop("placeholder",this.options.secondaryPlaceholder)}},{key:"_isValid",value:function(t){if(t.hasOwnProperty("tag")&&""!==t.tag){for(var e=!1,i=0;i=this.options.limit)){var e=this._renderChip(t);this.$chips.add(e),this.chipsData.push(t),h(this.$input).before(e),this._setPlaceholder(),"function"==typeof this.options.onChipAdd&&this.options.onChipAdd.call(this,this.$el,e)}}},{key:"deleteChip",value:function(t){var e=this.$chips.eq(t);this.$chips.eq(t).remove(),this.$chips=this.$chips.filter(function(t){return 0<=h(t).index()}),this.chipsData.splice(t,1),this._setPlaceholder(),"function"==typeof this.options.onChipDelete&&this.options.onChipDelete.call(this,this.$el,e[0])}},{key:"selectChip",value:function(t){var e=this.$chips.eq(t);(this._selectedChip=e)[0].focus(),"function"==typeof this.options.onChipSelect&&this.options.onChipSelect.call(this,this.$el,e[0])}}],[{key:"init",value:function(t,e){return _get(l.__proto__||Object.getPrototypeOf(l),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Chips}},{key:"_handleChipsKeydown",value:function(t){l._keydown=!0;var e=h(t.target).closest(".chips"),i=t.target&&e.length;if(!h(t.target).is("input, textarea")&&i){var n=e[0].M_Chips;if(8===t.keyCode||46===t.keyCode){t.preventDefault();var s=n.chipsData.length;if(n._selectedChip){var o=n._selectedChip.index();n.deleteChip(o),n._selectedChip=null,s=Math.max(o-1,0)}n.chipsData.length&&n.selectChip(s)}else if(37===t.keyCode){if(n._selectedChip){var a=n._selectedChip.index()-1;if(a<0)return;n.selectChip(a)}}else if(39===t.keyCode&&n._selectedChip){var r=n._selectedChip.index()+1;r>=n.chipsData.length?n.$input[0].focus():n.selectChip(r)}}}},{key:"_handleChipsKeyup",value:function(t){l._keydown=!1}},{key:"_handleChipsBlur",value:function(t){l._keydown||(h(t.target).closest(".chips")[0].M_Chips._selectedChip=null)}},{key:"defaults",get:function(){return e}}]),l}();t._keydown=!1,M.Chips=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"chips","M_Chips"),h(document).ready(function(){h(document.body).on("click",".chip .close",function(){var t=h(this).closest(".chips");t.length&&t[0].M_Chips||h(this).closest(".chip").remove()})})}(cash),function(s){"use strict";var e={top:0,bottom:1/0,offset:0,onPositionChange:null},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_Pushpin=i).options=s.extend({},n.defaults,e),i.originalOffset=i.el.offsetTop,n._pushpins.push(i),i._setupEventHandlers(),i._updatePosition(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this.el.style.top=null,this._removePinClasses(),this._removeEventHandlers();var t=n._pushpins.indexOf(this);n._pushpins.splice(t,1)}},{key:"_setupEventHandlers",value:function(){document.addEventListener("scroll",n._updateElements)}},{key:"_removeEventHandlers",value:function(){document.removeEventListener("scroll",n._updateElements)}},{key:"_updatePosition",value:function(){var t=M.getDocumentScrollTop()+this.options.offset;this.options.top<=t&&this.options.bottom>=t&&!this.el.classList.contains("pinned")&&(this._removePinClasses(),this.el.style.top=this.options.offset+"px",this.el.classList.add("pinned"),"function"==typeof this.options.onPositionChange&&this.options.onPositionChange.call(this,"pinned")),tthis.options.bottom&&!this.el.classList.contains("pin-bottom")&&(this._removePinClasses(),this.el.classList.add("pin-bottom"),this.el.style.top=this.options.bottom-this.originalOffset+"px","function"==typeof this.options.onPositionChange&&this.options.onPositionChange.call(this,"pin-bottom"))}},{key:"_removePinClasses",value:function(){this.el.classList.remove("pin-top"),this.el.classList.remove("pinned"),this.el.classList.remove("pin-bottom")}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Pushpin}},{key:"_updateElements",value:function(){for(var t in n._pushpins){n._pushpins[t]._updatePosition()}}},{key:"defaults",get:function(){return e}}]),n}();t._pushpins=[],M.Pushpin=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"pushpin","M_Pushpin")}(cash),function(r,s){"use strict";var e={direction:"top",hoverEnabled:!0,toolbarEnabled:!1};r.fn.reverse=[].reverse;var t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_FloatingActionButton=i).options=r.extend({},n.defaults,e),i.isOpen=!1,i.$anchor=i.$el.children("a").first(),i.$menu=i.$el.children("ul").first(),i.$floatingBtns=i.$el.find("ul .btn-floating"),i.$floatingBtnsReverse=i.$el.find("ul .btn-floating").reverse(),i.offsetY=0,i.offsetX=0,i.$el.addClass("direction-"+i.options.direction),"top"===i.options.direction?i.offsetY=40:"right"===i.options.direction?i.offsetX=-40:"bottom"===i.options.direction?i.offsetY=-40:i.offsetX=40,i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this._removeEventHandlers(),this.el.M_FloatingActionButton=void 0}},{key:"_setupEventHandlers",value:function(){this._handleFABClickBound=this._handleFABClick.bind(this),this._handleOpenBound=this.open.bind(this),this._handleCloseBound=this.close.bind(this),this.options.hoverEnabled&&!this.options.toolbarEnabled?(this.el.addEventListener("mouseenter",this._handleOpenBound),this.el.addEventListener("mouseleave",this._handleCloseBound)):this.el.addEventListener("click",this._handleFABClickBound)}},{key:"_removeEventHandlers",value:function(){this.options.hoverEnabled&&!this.options.toolbarEnabled?(this.el.removeEventListener("mouseenter",this._handleOpenBound),this.el.removeEventListener("mouseleave",this._handleCloseBound)):this.el.removeEventListener("click",this._handleFABClickBound)}},{key:"_handleFABClick",value:function(){this.isOpen?this.close():this.open()}},{key:"_handleDocumentClick",value:function(t){r(t.target).closest(this.$menu).length||this.close()}},{key:"open",value:function(){this.isOpen||(this.options.toolbarEnabled?this._animateInToolbar():this._animateInFAB(),this.isOpen=!0)}},{key:"close",value:function(){this.isOpen&&(this.options.toolbarEnabled?(window.removeEventListener("scroll",this._handleCloseBound,!0),document.body.removeEventListener("click",this._handleDocumentClickBound,!0),this._animateOutToolbar()):this._animateOutFAB(),this.isOpen=!1)}},{key:"_animateInFAB",value:function(){var e=this;this.$el.addClass("active");var i=0;this.$floatingBtnsReverse.each(function(t){s({targets:t,opacity:1,scale:[.4,1],translateY:[e.offsetY,0],translateX:[e.offsetX,0],duration:275,delay:i,easing:"easeInOutQuad"}),i+=40})}},{key:"_animateOutFAB",value:function(){var e=this;this.$floatingBtnsReverse.each(function(t){s.remove(t),s({targets:t,opacity:0,scale:.4,translateY:e.offsetY,translateX:e.offsetX,duration:175,easing:"easeOutQuad",complete:function(){e.$el.removeClass("active")}})})}},{key:"_animateInToolbar",value:function(){var t,e=this,i=window.innerWidth,n=window.innerHeight,s=this.el.getBoundingClientRect(),o=r('
    '),a=this.$anchor.css("background-color");this.$anchor.append(o),this.offsetX=s.left-i/2+s.width/2,this.offsetY=n-s.bottom,t=i/o[0].clientWidth,this.btnBottom=s.bottom,this.btnLeft=s.left,this.btnWidth=s.width,this.$el.addClass("active"),this.$el.css({"text-align":"center",width:"100%",bottom:0,left:0,transform:"translateX("+this.offsetX+"px)",transition:"none"}),this.$anchor.css({transform:"translateY("+-this.offsetY+"px)",transition:"none"}),o.css({"background-color":a}),setTimeout(function(){e.$el.css({transform:"",transition:"transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s"}),e.$anchor.css({overflow:"visible",transform:"",transition:"transform .2s"}),setTimeout(function(){e.$el.css({overflow:"hidden","background-color":a}),o.css({transform:"scale("+t+")",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"}),e.$menu.children("li").children("a").css({opacity:1}),e._handleDocumentClickBound=e._handleDocumentClick.bind(e),window.addEventListener("scroll",e._handleCloseBound,!0),document.body.addEventListener("click",e._handleDocumentClickBound,!0)},100)},0)}},{key:"_animateOutToolbar",value:function(){var t=this,e=window.innerWidth,i=window.innerHeight,n=this.$el.find(".fab-backdrop"),s=this.$anchor.css("background-color");this.offsetX=this.btnLeft-e/2+this.btnWidth/2,this.offsetY=i-this.btnBottom,this.$el.removeClass("active"),this.$el.css({"background-color":"transparent",transition:"none"}),this.$anchor.css({transition:"none"}),n.css({transform:"scale(0)","background-color":s}),this.$menu.children("li").children("a").css({opacity:""}),setTimeout(function(){n.remove(),t.$el.css({"text-align":"",width:"",bottom:"",left:"",overflow:"","background-color":"",transform:"translate3d("+-t.offsetX+"px,0,0)"}),t.$anchor.css({overflow:"",transform:"translate3d(0,"+t.offsetY+"px,0)"}),setTimeout(function(){t.$el.css({transform:"translate3d(0,0,0)",transition:"transform .2s"}),t.$anchor.css({transform:"translate3d(0,0,0)",transition:"transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)"})},20)},200)}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_FloatingActionButton}},{key:"defaults",get:function(){return e}}]),n}();M.FloatingActionButton=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"floatingActionButton","M_FloatingActionButton")}(cash,M.anime),function(g){"use strict";var e={autoClose:!1,format:"mmm dd, yyyy",parse:null,defaultDate:null,setDefaultDate:!1,disableWeekends:!1,disableDayFn:null,firstDay:0,minDate:null,maxDate:null,yearRange:10,minYear:0,maxYear:9999,minMonth:void 0,maxMonth:void 0,startRange:null,endRange:null,isRTL:!1,showMonthAfterYear:!1,showDaysInNextAndPreviousMonths:!1,container:null,showClearBtn:!1,i18n:{cancel:"Cancel",clear:"Clear",done:"Ok",previousMonth:"‹",nextMonth:"›",months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],weekdaysAbbrev:["S","M","T","W","T","F","S"]},events:[],onSelect:null,onOpen:null,onClose:null,onDraw:null},t=function(t){function B(t,e){_classCallCheck(this,B);var i=_possibleConstructorReturn(this,(B.__proto__||Object.getPrototypeOf(B)).call(this,B,t,e));(i.el.M_Datepicker=i).options=g.extend({},B.defaults,e),e&&e.hasOwnProperty("i18n")&&"object"==typeof e.i18n&&(i.options.i18n=g.extend({},B.defaults.i18n,e.i18n)),i.options.minDate&&i.options.minDate.setHours(0,0,0,0),i.options.maxDate&&i.options.maxDate.setHours(0,0,0,0),i.id=M.guid(),i._setupVariables(),i._insertHTMLIntoDOM(),i._setupModal(),i._setupEventHandlers(),i.options.defaultDate||(i.options.defaultDate=new Date(Date.parse(i.el.value)));var n=i.options.defaultDate;return B._isDate(n)?i.options.setDefaultDate?(i.setDate(n,!0),i.setInputValue()):i.gotoDate(n):i.gotoDate(new Date),i.isOpen=!1,i}return _inherits(B,Component),_createClass(B,[{key:"destroy",value:function(){this._removeEventHandlers(),this.modal.destroy(),g(this.modalEl).remove(),this.destroySelects(),this.el.M_Datepicker=void 0}},{key:"destroySelects",value:function(){var t=this.calendarEl.querySelector(".orig-select-year");t&&M.FormSelect.getInstance(t).destroy();var e=this.calendarEl.querySelector(".orig-select-month");e&&M.FormSelect.getInstance(e).destroy()}},{key:"_insertHTMLIntoDOM",value:function(){this.options.showClearBtn&&(g(this.clearBtn).css({visibility:""}),this.clearBtn.innerHTML=this.options.i18n.clear),this.doneBtn.innerHTML=this.options.i18n.done,this.cancelBtn.innerHTML=this.options.i18n.cancel,this.options.container?this.$modalEl.appendTo(this.options.container):this.$modalEl.insertBefore(this.el)}},{key:"_setupModal",value:function(){var t=this;this.modalEl.id="modal-"+this.id,this.modal=M.Modal.init(this.modalEl,{onCloseEnd:function(){t.isOpen=!1}})}},{key:"toString",value:function(t){var e=this;return t=t||this.options.format,B._isDate(this.date)?t.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g).map(function(t){return e.formats[t]?e.formats[t]():t}).join(""):""}},{key:"setDate",value:function(t,e){if(!t)return this.date=null,this._renderDateDisplay(),this.draw();if("string"==typeof t&&(t=new Date(Date.parse(t))),B._isDate(t)){var i=this.options.minDate,n=this.options.maxDate;B._isDate(i)&&tn.maxDate||n.disableWeekends&&B._isWeekend(y)||n.disableDayFn&&n.disableDayFn(y),isEmpty:C,isStartRange:x,isEndRange:L,isInRange:T,showDaysInNextAndPreviousMonths:n.showDaysInNextAndPreviousMonths};l.push(this.renderDay($)),7==++_&&(r.push(this.renderRow(l,n.isRTL,m)),_=0,m=!(l=[]))}return this.renderTable(n,r,i)}},{key:"renderDay",value:function(t){var e=[],i="false";if(t.isEmpty){if(!t.showDaysInNextAndPreviousMonths)return'';e.push("is-outside-current-month"),e.push("is-selection-disabled")}return t.isDisabled&&e.push("is-disabled"),t.isToday&&e.push("is-today"),t.isSelected&&(e.push("is-selected"),i="true"),t.hasEvent&&e.push("has-event"),t.isInRange&&e.push("is-inrange"),t.isStartRange&&e.push("is-startrange"),t.isEndRange&&e.push("is-endrange"),'"}},{key:"renderRow",value:function(t,e,i){return''+(e?t.reverse():t).join("")+""}},{key:"renderTable",value:function(t,e,i){return'
    '+this.renderHead(t)+this.renderBody(e)+"
    "}},{key:"renderHead",value:function(t){var e=void 0,i=[];for(e=0;e<7;e++)i.push(''+this.renderDayName(t,e,!0)+"");return""+(t.isRTL?i.reverse():i).join("")+""}},{key:"renderBody",value:function(t){return""+t.join("")+""}},{key:"renderTitle",value:function(t,e,i,n,s,o){var a,r,l=void 0,h=void 0,d=void 0,u=this.options,c=i===u.minYear,p=i===u.maxYear,v='
    ',f=!0,m=!0;for(d=[],l=0;l<12;l++)d.push('");for(a='",g.isArray(u.yearRange)?(l=u.yearRange[0],h=u.yearRange[1]+1):(l=i-u.yearRange,h=1+i+u.yearRange),d=[];l=u.minYear&&d.push('");r='";v+='',v+='
    ',u.showMonthAfterYear?v+=r+a:v+=a+r,v+="
    ",c&&(0===n||u.minMonth>=n)&&(f=!1),p&&(11===n||u.maxMonth<=n)&&(m=!1);return(v+='')+"
    "}},{key:"draw",value:function(t){if(this.isOpen||t){var e,i=this.options,n=i.minYear,s=i.maxYear,o=i.minMonth,a=i.maxMonth,r="";this._y<=n&&(this._y=n,!isNaN(o)&&this._m=s&&(this._y=s,!isNaN(a)&&this._m>a&&(this._m=a)),e="datepicker-title-"+Math.random().toString(36).replace(/[^a-z]+/g,"").substr(0,2);for(var l=0;l<1;l++)this._renderDateDisplay(),r+=this.renderTitle(this,l,this.calendars[l].year,this.calendars[l].month,this.calendars[0].year,e)+this.render(this.calendars[l].year,this.calendars[l].month,e);this.destroySelects(),this.calendarEl.innerHTML=r;var h=this.calendarEl.querySelector(".orig-select-year"),d=this.calendarEl.querySelector(".orig-select-month");M.FormSelect.init(h,{classes:"select-year",dropdownOptions:{container:document.body,constrainWidth:!1}}),M.FormSelect.init(d,{classes:"select-month",dropdownOptions:{container:document.body,constrainWidth:!1}}),h.addEventListener("change",this._handleYearChange.bind(this)),d.addEventListener("change",this._handleMonthChange.bind(this)),"function"==typeof this.options.onDraw&&this.options.onDraw(this)}}},{key:"_setupEventHandlers",value:function(){this._handleInputKeydownBound=this._handleInputKeydown.bind(this),this._handleInputClickBound=this._handleInputClick.bind(this),this._handleInputChangeBound=this._handleInputChange.bind(this),this._handleCalendarClickBound=this._handleCalendarClick.bind(this),this._finishSelectionBound=this._finishSelection.bind(this),this._handleMonthChange=this._handleMonthChange.bind(this),this._closeBound=this.close.bind(this),this.el.addEventListener("click",this._handleInputClickBound),this.el.addEventListener("keydown",this._handleInputKeydownBound),this.el.addEventListener("change",this._handleInputChangeBound),this.calendarEl.addEventListener("click",this._handleCalendarClickBound),this.doneBtn.addEventListener("click",this._finishSelectionBound),this.cancelBtn.addEventListener("click",this._closeBound),this.options.showClearBtn&&(this._handleClearClickBound=this._handleClearClick.bind(this),this.clearBtn.addEventListener("click",this._handleClearClickBound))}},{key:"_setupVariables",value:function(){var e=this;this.$modalEl=g(B._template),this.modalEl=this.$modalEl[0],this.calendarEl=this.modalEl.querySelector(".datepicker-calendar"),this.yearTextEl=this.modalEl.querySelector(".year-text"),this.dateTextEl=this.modalEl.querySelector(".date-text"),this.options.showClearBtn&&(this.clearBtn=this.modalEl.querySelector(".datepicker-clear")),this.doneBtn=this.modalEl.querySelector(".datepicker-done"),this.cancelBtn=this.modalEl.querySelector(".datepicker-cancel"),this.formats={d:function(){return e.date.getDate()},dd:function(){var t=e.date.getDate();return(t<10?"0":"")+t},ddd:function(){return e.options.i18n.weekdaysShort[e.date.getDay()]},dddd:function(){return e.options.i18n.weekdays[e.date.getDay()]},m:function(){return e.date.getMonth()+1},mm:function(){var t=e.date.getMonth()+1;return(t<10?"0":"")+t},mmm:function(){return e.options.i18n.monthsShort[e.date.getMonth()]},mmmm:function(){return e.options.i18n.months[e.date.getMonth()]},yy:function(){return(""+e.date.getFullYear()).slice(2)},yyyy:function(){return e.date.getFullYear()}}}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("click",this._handleInputClickBound),this.el.removeEventListener("keydown",this._handleInputKeydownBound),this.el.removeEventListener("change",this._handleInputChangeBound),this.calendarEl.removeEventListener("click",this._handleCalendarClickBound)}},{key:"_handleInputClick",value:function(){this.open()}},{key:"_handleInputKeydown",value:function(t){t.which===M.keys.ENTER&&(t.preventDefault(),this.open())}},{key:"_handleCalendarClick",value:function(t){if(this.isOpen){var e=g(t.target);e.hasClass("is-disabled")||(!e.hasClass("datepicker-day-button")||e.hasClass("is-empty")||e.parent().hasClass("is-disabled")?e.closest(".month-prev").length?this.prevMonth():e.closest(".month-next").length&&this.nextMonth():(this.setDate(new Date(t.target.getAttribute("data-year"),t.target.getAttribute("data-month"),t.target.getAttribute("data-day"))),this.options.autoClose&&this._finishSelection()))}}},{key:"_handleClearClick",value:function(){this.date=null,this.setInputValue(),this.close()}},{key:"_handleMonthChange",value:function(t){this.gotoMonth(t.target.value)}},{key:"_handleYearChange",value:function(t){this.gotoYear(t.target.value)}},{key:"gotoMonth",value:function(t){isNaN(t)||(this.calendars[0].month=parseInt(t,10),this.adjustCalendars())}},{key:"gotoYear",value:function(t){isNaN(t)||(this.calendars[0].year=parseInt(t,10),this.adjustCalendars())}},{key:"_handleInputChange",value:function(t){var e=void 0;t.firedBy!==this&&(e=this.options.parse?this.options.parse(this.el.value,this.options.format):new Date(Date.parse(this.el.value)),B._isDate(e)&&this.setDate(e))}},{key:"renderDayName",value:function(t,e,i){for(e+=t.firstDay;7<=e;)e-=7;return i?t.i18n.weekdaysAbbrev[e]:t.i18n.weekdays[e]}},{key:"_finishSelection",value:function(){this.setInputValue(),this.close()}},{key:"open",value:function(){if(!this.isOpen)return this.isOpen=!0,"function"==typeof this.options.onOpen&&this.options.onOpen.call(this),this.draw(),this.modal.open(),this}},{key:"close",value:function(){if(this.isOpen)return this.isOpen=!1,"function"==typeof this.options.onClose&&this.options.onClose.call(this),this.modal.close(),this}}],[{key:"init",value:function(t,e){return _get(B.__proto__||Object.getPrototypeOf(B),"init",this).call(this,this,t,e)}},{key:"_isDate",value:function(t){return/Date/.test(Object.prototype.toString.call(t))&&!isNaN(t.getTime())}},{key:"_isWeekend",value:function(t){var e=t.getDay();return 0===e||6===e}},{key:"_setToStartOfDay",value:function(t){B._isDate(t)&&t.setHours(0,0,0,0)}},{key:"_getDaysInMonth",value:function(t,e){return[31,B._isLeapYear(t)?29:28,31,30,31,30,31,31,30,31,30,31][e]}},{key:"_isLeapYear",value:function(t){return t%4==0&&t%100!=0||t%400==0}},{key:"_compareDates",value:function(t,e){return t.getTime()===e.getTime()}},{key:"_setToStartOfDay",value:function(t){B._isDate(t)&&t.setHours(0,0,0,0)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Datepicker}},{key:"defaults",get:function(){return e}}]),B}();t._template=['"].join(""),M.Datepicker=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"datepicker","M_Datepicker")}(cash),function(h){"use strict";var e={dialRadius:135,outerRadius:105,innerRadius:70,tickRadius:20,duration:350,container:null,defaultTime:"now",fromNow:0,showClearBtn:!1,i18n:{cancel:"Cancel",clear:"Clear",done:"Ok"},autoClose:!1,twelveHour:!0,vibrate:!0,onOpenStart:null,onOpenEnd:null,onCloseStart:null,onCloseEnd:null,onSelect:null},t=function(t){function f(t,e){_classCallCheck(this,f);var i=_possibleConstructorReturn(this,(f.__proto__||Object.getPrototypeOf(f)).call(this,f,t,e));return(i.el.M_Timepicker=i).options=h.extend({},f.defaults,e),i.id=M.guid(),i._insertHTMLIntoDOM(),i._setupModal(),i._setupVariables(),i._setupEventHandlers(),i._clockSetup(),i._pickerSetup(),i}return _inherits(f,Component),_createClass(f,[{key:"destroy",value:function(){this._removeEventHandlers(),this.modal.destroy(),h(this.modalEl).remove(),this.el.M_Timepicker=void 0}},{key:"_setupEventHandlers",value:function(){this._handleInputKeydownBound=this._handleInputKeydown.bind(this),this._handleInputClickBound=this._handleInputClick.bind(this),this._handleClockClickStartBound=this._handleClockClickStart.bind(this),this._handleDocumentClickMoveBound=this._handleDocumentClickMove.bind(this),this._handleDocumentClickEndBound=this._handleDocumentClickEnd.bind(this),this.el.addEventListener("click",this._handleInputClickBound),this.el.addEventListener("keydown",this._handleInputKeydownBound),this.plate.addEventListener("mousedown",this._handleClockClickStartBound),this.plate.addEventListener("touchstart",this._handleClockClickStartBound),h(this.spanHours).on("click",this.showView.bind(this,"hours")),h(this.spanMinutes).on("click",this.showView.bind(this,"minutes"))}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("click",this._handleInputClickBound),this.el.removeEventListener("keydown",this._handleInputKeydownBound)}},{key:"_handleInputClick",value:function(){this.open()}},{key:"_handleInputKeydown",value:function(t){t.which===M.keys.ENTER&&(t.preventDefault(),this.open())}},{key:"_handleClockClickStart",value:function(t){t.preventDefault();var e=this.plate.getBoundingClientRect(),i=e.left,n=e.top;this.x0=i+this.options.dialRadius,this.y0=n+this.options.dialRadius,this.moved=!1;var s=f._Pos(t);this.dx=s.x-this.x0,this.dy=s.y-this.y0,this.setHand(this.dx,this.dy,!1),document.addEventListener("mousemove",this._handleDocumentClickMoveBound),document.addEventListener("touchmove",this._handleDocumentClickMoveBound),document.addEventListener("mouseup",this._handleDocumentClickEndBound),document.addEventListener("touchend",this._handleDocumentClickEndBound)}},{key:"_handleDocumentClickMove",value:function(t){t.preventDefault();var e=f._Pos(t),i=e.x-this.x0,n=e.y-this.y0;this.moved=!0,this.setHand(i,n,!1,!0)}},{key:"_handleDocumentClickEnd",value:function(t){var e=this;t.preventDefault(),document.removeEventListener("mouseup",this._handleDocumentClickEndBound),document.removeEventListener("touchend",this._handleDocumentClickEndBound);var i=f._Pos(t),n=i.x-this.x0,s=i.y-this.y0;this.moved&&n===this.dx&&s===this.dy&&this.setHand(n,s),"hours"===this.currentView?this.showView("minutes",this.options.duration/2):this.options.autoClose&&(h(this.minutesView).addClass("timepicker-dial-out"),setTimeout(function(){e.done()},this.options.duration/2)),"function"==typeof this.options.onSelect&&this.options.onSelect.call(this,this.hours,this.minutes),document.removeEventListener("mousemove",this._handleDocumentClickMoveBound),document.removeEventListener("touchmove",this._handleDocumentClickMoveBound)}},{key:"_insertHTMLIntoDOM",value:function(){this.$modalEl=h(f._template),this.modalEl=this.$modalEl[0],this.modalEl.id="modal-"+this.id;var t=document.querySelector(this.options.container);this.options.container&&t?this.$modalEl.appendTo(t):this.$modalEl.insertBefore(this.el)}},{key:"_setupModal",value:function(){var t=this;this.modal=M.Modal.init(this.modalEl,{onOpenStart:this.options.onOpenStart,onOpenEnd:this.options.onOpenEnd,onCloseStart:this.options.onCloseStart,onCloseEnd:function(){"function"==typeof t.options.onCloseEnd&&t.options.onCloseEnd.call(t),t.isOpen=!1}})}},{key:"_setupVariables",value:function(){this.currentView="hours",this.vibrate=navigator.vibrate?"vibrate":navigator.webkitVibrate?"webkitVibrate":null,this._canvas=this.modalEl.querySelector(".timepicker-canvas"),this.plate=this.modalEl.querySelector(".timepicker-plate"),this.hoursView=this.modalEl.querySelector(".timepicker-hours"),this.minutesView=this.modalEl.querySelector(".timepicker-minutes"),this.spanHours=this.modalEl.querySelector(".timepicker-span-hours"),this.spanMinutes=this.modalEl.querySelector(".timepicker-span-minutes"),this.spanAmPm=this.modalEl.querySelector(".timepicker-span-am-pm"),this.footer=this.modalEl.querySelector(".timepicker-footer"),this.amOrPm="PM"}},{key:"_pickerSetup",value:function(){var t=h('").appendTo(this.footer).on("click",this.clear.bind(this));this.options.showClearBtn&&t.css({visibility:""});var e=h('
    ');h('").appendTo(e).on("click",this.close.bind(this)),h('").appendTo(e).on("click",this.done.bind(this)),e.appendTo(this.footer)}},{key:"_clockSetup",value:function(){this.options.twelveHour&&(this.$amBtn=h('
    AM
    '),this.$pmBtn=h('
    PM
    '),this.$amBtn.on("click",this._handleAmPmClick.bind(this)).appendTo(this.spanAmPm),this.$pmBtn.on("click",this._handleAmPmClick.bind(this)).appendTo(this.spanAmPm)),this._buildHoursView(),this._buildMinutesView(),this._buildSVGClock()}},{key:"_buildSVGClock",value:function(){var t=this.options.dialRadius,e=this.options.tickRadius,i=2*t,n=f._createSVGEl("svg");n.setAttribute("class","timepicker-svg"),n.setAttribute("width",i),n.setAttribute("height",i);var s=f._createSVGEl("g");s.setAttribute("transform","translate("+t+","+t+")");var o=f._createSVGEl("circle");o.setAttribute("class","timepicker-canvas-bearing"),o.setAttribute("cx",0),o.setAttribute("cy",0),o.setAttribute("r",4);var a=f._createSVGEl("line");a.setAttribute("x1",0),a.setAttribute("y1",0);var r=f._createSVGEl("circle");r.setAttribute("class","timepicker-canvas-bg"),r.setAttribute("r",e),s.appendChild(a),s.appendChild(r),s.appendChild(o),n.appendChild(s),this._canvas.appendChild(n),this.hand=a,this.bg=r,this.bearing=o,this.g=s}},{key:"_buildHoursView",value:function(){var t=h('
    ');if(this.options.twelveHour)for(var e=1;e<13;e+=1){var i=t.clone(),n=e/6*Math.PI,s=this.options.outerRadius;i.css({left:this.options.dialRadius+Math.sin(n)*s-this.options.tickRadius+"px",top:this.options.dialRadius-Math.cos(n)*s-this.options.tickRadius+"px"}),i.html(0===e?"00":e),this.hoursView.appendChild(i[0])}else for(var o=0;o<24;o+=1){var a=t.clone(),r=o/6*Math.PI,l=0'),e=0;e<60;e+=5){var i=t.clone(),n=e/30*Math.PI;i.css({left:this.options.dialRadius+Math.sin(n)*this.options.outerRadius-this.options.tickRadius+"px",top:this.options.dialRadius-Math.cos(n)*this.options.outerRadius-this.options.tickRadius+"px"}),i.html(f._addLeadingZero(e)),this.minutesView.appendChild(i[0])}}},{key:"_handleAmPmClick",value:function(t){var e=h(t.target);this.amOrPm=e.hasClass("am-btn")?"AM":"PM",this._updateAmPmView()}},{key:"_updateAmPmView",value:function(){this.options.twelveHour&&(this.$amBtn.toggleClass("text-primary","AM"===this.amOrPm),this.$pmBtn.toggleClass("text-primary","PM"===this.amOrPm))}},{key:"_updateTimeFromInput",value:function(){var t=((this.el.value||this.options.defaultTime||"")+"").split(":");if(this.options.twelveHour&&void 0!==t[1]&&(0','",""].join(""),M.Timepicker=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"timepicker","M_Timepicker")}(cash),function(s){"use strict";var e={},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_CharacterCounter=i).options=s.extend({},n.defaults,e),i.isInvalid=!1,i.isValidLength=!1,i._setupCounter(),i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this._removeEventHandlers(),this.el.CharacterCounter=void 0,this._removeCounter()}},{key:"_setupEventHandlers",value:function(){this._handleUpdateCounterBound=this.updateCounter.bind(this),this.el.addEventListener("focus",this._handleUpdateCounterBound,!0),this.el.addEventListener("input",this._handleUpdateCounterBound,!0)}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("focus",this._handleUpdateCounterBound,!0),this.el.removeEventListener("input",this._handleUpdateCounterBound,!0)}},{key:"_setupCounter",value:function(){this.counterEl=document.createElement("span"),s(this.counterEl).addClass("character-counter").css({float:"right","font-size":"12px",height:1}),this.$el.parent().append(this.counterEl)}},{key:"_removeCounter",value:function(){s(this.counterEl).remove()}},{key:"updateCounter",value:function(){var t=+this.$el.attr("data-length"),e=this.el.value.length;this.isValidLength=e<=t;var i=e;t&&(i+="/"+t,this._validateInput()),s(this.counterEl).html(i)}},{key:"_validateInput",value:function(){this.isValidLength&&this.isInvalid?(this.isInvalid=!1,this.$el.removeClass("invalid")):this.isValidLength||this.isInvalid||(this.isInvalid=!0,this.$el.removeClass("valid"),this.$el.addClass("invalid"))}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_CharacterCounter}},{key:"defaults",get:function(){return e}}]),n}();M.CharacterCounter=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"characterCounter","M_CharacterCounter")}(cash),function(b){"use strict";var e={duration:200,dist:-100,shift:0,padding:0,numVisible:5,fullWidth:!1,indicators:!1,noWrap:!1,onCycleTo:null},t=function(t){function i(t,e){_classCallCheck(this,i);var n=_possibleConstructorReturn(this,(i.__proto__||Object.getPrototypeOf(i)).call(this,i,t,e));return(n.el.M_Carousel=n).options=b.extend({},i.defaults,e),n.hasMultipleSlides=1'),n.$el.find(".carousel-item").each(function(t,e){if(n.images.push(t),n.showIndicators){var i=b('
  • ');0===e&&i[0].classList.add("active"),n.$indicators.append(i)}}),n.showIndicators&&n.$el.append(n.$indicators),n.count=n.images.length,n.options.numVisible=Math.min(n.count,n.options.numVisible),n.xform="transform",["webkit","Moz","O","ms"].every(function(t){var e=t+"Transform";return void 0===document.body.style[e]||(n.xform=e,!1)}),n._setupEventHandlers(),n._scroll(n.offset),n}return _inherits(i,Component),_createClass(i,[{key:"destroy",value:function(){this._removeEventHandlers(),this.el.M_Carousel=void 0}},{key:"_setupEventHandlers",value:function(){var i=this;this._handleCarouselTapBound=this._handleCarouselTap.bind(this),this._handleCarouselDragBound=this._handleCarouselDrag.bind(this),this._handleCarouselReleaseBound=this._handleCarouselRelease.bind(this),this._handleCarouselClickBound=this._handleCarouselClick.bind(this),void 0!==window.ontouchstart&&(this.el.addEventListener("touchstart",this._handleCarouselTapBound),this.el.addEventListener("touchmove",this._handleCarouselDragBound),this.el.addEventListener("touchend",this._handleCarouselReleaseBound)),this.el.addEventListener("mousedown",this._handleCarouselTapBound),this.el.addEventListener("mousemove",this._handleCarouselDragBound),this.el.addEventListener("mouseup",this._handleCarouselReleaseBound),this.el.addEventListener("mouseleave",this._handleCarouselReleaseBound),this.el.addEventListener("click",this._handleCarouselClickBound),this.showIndicators&&this.$indicators&&(this._handleIndicatorClickBound=this._handleIndicatorClick.bind(this),this.$indicators.find(".indicator-item").each(function(t,e){t.addEventListener("click",i._handleIndicatorClickBound)}));var t=M.throttle(this._handleResize,200);this._handleThrottledResizeBound=t.bind(this),window.addEventListener("resize",this._handleThrottledResizeBound)}},{key:"_removeEventHandlers",value:function(){var i=this;void 0!==window.ontouchstart&&(this.el.removeEventListener("touchstart",this._handleCarouselTapBound),this.el.removeEventListener("touchmove",this._handleCarouselDragBound),this.el.removeEventListener("touchend",this._handleCarouselReleaseBound)),this.el.removeEventListener("mousedown",this._handleCarouselTapBound),this.el.removeEventListener("mousemove",this._handleCarouselDragBound),this.el.removeEventListener("mouseup",this._handleCarouselReleaseBound),this.el.removeEventListener("mouseleave",this._handleCarouselReleaseBound),this.el.removeEventListener("click",this._handleCarouselClickBound),this.showIndicators&&this.$indicators&&this.$indicators.find(".indicator-item").each(function(t,e){t.removeEventListener("click",i._handleIndicatorClickBound)}),window.removeEventListener("resize",this._handleThrottledResizeBound)}},{key:"_handleCarouselTap",value:function(t){"mousedown"===t.type&&b(t.target).is("img")&&t.preventDefault(),this.pressed=!0,this.dragged=!1,this.verticalDragged=!1,this.reference=this._xpos(t),this.referenceY=this._ypos(t),this.velocity=this.amplitude=0,this.frame=this.offset,this.timestamp=Date.now(),clearInterval(this.ticker),this.ticker=setInterval(this._trackBound,100)}},{key:"_handleCarouselDrag",value:function(t){var e=void 0,i=void 0,n=void 0;if(this.pressed)if(e=this._xpos(t),i=this._ypos(t),n=this.reference-e,Math.abs(this.referenceY-i)<30&&!this.verticalDragged)(2=this.dim*(this.count-1)?this.target=this.dim*(this.count-1):this.target<0&&(this.target=0)),this.amplitude=this.target-this.offset,this.timestamp=Date.now(),requestAnimationFrame(this._autoScrollBound),this.dragged&&(t.preventDefault(),t.stopPropagation()),!1}},{key:"_handleCarouselClick",value:function(t){if(this.dragged)return t.preventDefault(),t.stopPropagation(),!1;if(!this.options.fullWidth){var e=b(t.target).closest(".carousel-item").index();0!==this._wrap(this.center)-e&&(t.preventDefault(),t.stopPropagation()),this._cycleTo(e)}}},{key:"_handleIndicatorClick",value:function(t){t.stopPropagation();var e=b(t.target).closest(".indicator-item");e.length&&this._cycleTo(e.index())}},{key:"_handleResize",value:function(t){this.options.fullWidth?(this.itemWidth=this.$el.find(".carousel-item").first().innerWidth(),this.imageHeight=this.$el.find(".carousel-item.active").height(),this.dim=2*this.itemWidth+this.options.padding,this.offset=2*this.center*this.itemWidth,this.target=this.offset,this._setCarouselHeight(!0)):this._scroll()}},{key:"_setCarouselHeight",value:function(t){var i=this,e=this.$el.find(".carousel-item.active").length?this.$el.find(".carousel-item.active").first():this.$el.find(".carousel-item").first(),n=e.find("img").first();if(n.length)if(n[0].complete){var s=n.height();if(0=this.count?t%this.count:t<0?this._wrap(this.count+t%this.count):t}},{key:"_track",value:function(){var t,e,i,n;e=(t=Date.now())-this.timestamp,this.timestamp=t,i=this.offset-this.frame,this.frame=this.offset,n=1e3*i/(1+e),this.velocity=.8*n+.2*this.velocity}},{key:"_autoScroll",value:function(){var t=void 0,e=void 0;this.amplitude&&(t=Date.now()-this.timestamp,2<(e=this.amplitude*Math.exp(-t/this.options.duration))||e<-2?(this._scroll(this.target-e),requestAnimationFrame(this._autoScrollBound)):this._scroll(this.target))}},{key:"_scroll",value:function(t){var e=this;this.$el.hasClass("scrolling")||this.el.classList.add("scrolling"),null!=this.scrollingTimeout&&window.clearTimeout(this.scrollingTimeout),this.scrollingTimeout=window.setTimeout(function(){e.$el.removeClass("scrolling")},this.options.duration);var i,n,s,o,a=void 0,r=void 0,l=void 0,h=void 0,d=void 0,u=void 0,c=this.center,p=1/this.options.numVisible;if(this.offset="number"==typeof t?t:this.offset,this.center=Math.floor((this.offset+this.dim/2)/this.dim),o=-(s=(n=this.offset-this.center*this.dim)<0?1:-1)*n*2/this.dim,i=this.count>>1,this.options.fullWidth?(l="translateX(0)",u=1):(l="translateX("+(this.el.clientWidth-this.itemWidth)/2+"px) ",l+="translateY("+(this.el.clientHeight-this.itemHeight)/2+"px)",u=1-p*o),this.showIndicators){var v=this.center%this.count,f=this.$indicators.find(".indicator-item.active");f.index()!==v&&(f.removeClass("active"),this.$indicators.find(".indicator-item").eq(v)[0].classList.add("active"))}if(!this.noWrap||0<=this.center&&this.center=this.count||e<0){if(this.noWrap)return;e=this._wrap(e)}this._cycleTo(e)}},{key:"prev",value:function(t){(void 0===t||isNaN(t))&&(t=1);var e=this.center-t;if(e>=this.count||e<0){if(this.noWrap)return;e=this._wrap(e)}this._cycleTo(e)}},{key:"set",value:function(t,e){if((void 0===t||isNaN(t))&&(t=0),t>this.count||t<0){if(this.noWrap)return;t=this._wrap(t)}this._cycleTo(t,e)}}],[{key:"init",value:function(t,e){return _get(i.__proto__||Object.getPrototypeOf(i),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Carousel}},{key:"defaults",get:function(){return e}}]),i}();M.Carousel=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"carousel","M_Carousel")}(cash),function(S){"use strict";var e={onOpen:void 0,onClose:void 0},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_TapTarget=i).options=S.extend({},n.defaults,e),i.isOpen=!1,i.$origin=S("#"+i.$el.attr("data-target")),i._setup(),i._calculatePositioning(),i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this._removeEventHandlers(),this.el.TapTarget=void 0}},{key:"_setupEventHandlers",value:function(){this._handleDocumentClickBound=this._handleDocumentClick.bind(this),this._handleTargetClickBound=this._handleTargetClick.bind(this),this._handleOriginClickBound=this._handleOriginClick.bind(this),this.el.addEventListener("click",this._handleTargetClickBound),this.originEl.addEventListener("click",this._handleOriginClickBound);var t=M.throttle(this._handleResize,200);this._handleThrottledResizeBound=t.bind(this),window.addEventListener("resize",this._handleThrottledResizeBound)}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("click",this._handleTargetClickBound),this.originEl.removeEventListener("click",this._handleOriginClickBound),window.removeEventListener("resize",this._handleThrottledResizeBound)}},{key:"_handleTargetClick",value:function(t){this.open()}},{key:"_handleOriginClick",value:function(t){this.close()}},{key:"_handleResize",value:function(t){this._calculatePositioning()}},{key:"_handleDocumentClick",value:function(t){S(t.target).closest(".tap-target-wrapper").length||(this.close(),t.preventDefault(),t.stopPropagation())}},{key:"_setup",value:function(){this.wrapper=this.$el.parent()[0],this.waveEl=S(this.wrapper).find(".tap-target-wave")[0],this.originEl=S(this.wrapper).find(".tap-target-origin")[0],this.contentEl=this.$el.find(".tap-target-content")[0],S(this.wrapper).hasClass(".tap-target-wrapper")||(this.wrapper=document.createElement("div"),this.wrapper.classList.add("tap-target-wrapper"),this.$el.before(S(this.wrapper)),this.wrapper.append(this.el)),this.contentEl||(this.contentEl=document.createElement("div"),this.contentEl.classList.add("tap-target-content"),this.$el.append(this.contentEl)),this.waveEl||(this.waveEl=document.createElement("div"),this.waveEl.classList.add("tap-target-wave"),this.originEl||(this.originEl=this.$origin.clone(!0,!0),this.originEl.addClass("tap-target-origin"),this.originEl.removeAttr("id"),this.originEl.removeAttr("style"),this.originEl=this.originEl[0],this.waveEl.append(this.originEl)),this.wrapper.append(this.waveEl))}},{key:"_calculatePositioning",value:function(){var t="fixed"===this.$origin.css("position");if(!t)for(var e=this.$origin.parents(),i=0;i'+t.getAttribute("label")+"")[0]),i.each(function(t){var e=n._appendOptionWithIcon(n.$el,t,"optgroup-option");n._addOptionToValueDict(t,e)})}}),this.$el.after(this.dropdownOptions),this.input=document.createElement("input"),d(this.input).addClass("select-dropdown dropdown-trigger"),this.input.setAttribute("type","text"),this.input.setAttribute("readonly","true"),this.input.setAttribute("data-target",this.dropdownOptions.id),this.el.disabled&&d(this.input).prop("disabled","true"),this.$el.before(this.input),this._setValueToInput();var t=d('');if(this.$el.before(t[0]),!this.el.disabled){var e=d.extend({},this.options.dropdownOptions);e.onOpenEnd=function(t){var e=d(n.dropdownOptions).find(".selected").first();if(e.length&&(M.keyDown=!0,n.dropdown.focusedIndex=e.index(),n.dropdown._focusFocusedItem(),M.keyDown=!1,n.dropdown.isScrollable)){var i=e[0].getBoundingClientRect().top-n.dropdownOptions.getBoundingClientRect().top;i-=n.dropdownOptions.clientHeight/2,n.dropdownOptions.scrollTop=i}},this.isMultiple&&(e.closeOnClick=!1),this.dropdown=M.Dropdown.init(this.input,e)}this._setSelectedStates()}},{key:"_addOptionToValueDict",value:function(t,e){var i=Object.keys(this._valueDict).length,n=this.dropdownOptions.id+i,s={};e.id=n,s.el=t,s.optionEl=e,this._valueDict[n]=s}},{key:"_removeDropdown",value:function(){d(this.wrapper).find(".caret").remove(),d(this.input).remove(),d(this.dropdownOptions).remove(),d(this.wrapper).before(this.$el),d(this.wrapper).remove()}},{key:"_appendOptionWithIcon",value:function(t,e,i){var n=e.disabled?"disabled ":"",s="optgroup-option"===i?"optgroup-option ":"",o=this.isMultiple?'":e.innerHTML,a=d("
  • "),r=d("");r.html(o),a.addClass(n+" "+s),a.append(r);var l=e.getAttribute("data-icon");if(l){var h=d('');a.prepend(h)}return d(this.dropdownOptions).append(a[0]),a[0]}},{key:"_toggleEntryFromArray",value:function(t){var e=!this._keysSelected.hasOwnProperty(t),i=d(this._valueDict[t].optionEl);return e?this._keysSelected[t]=!0:delete this._keysSelected[t],i.toggleClass("selected",e),i.find('input[type="checkbox"]').prop("checked",e),i.prop("selected",e),e}},{key:"_setValueToInput",value:function(){var i=[];if(this.$el.find("option").each(function(t){if(d(t).prop("selected")){var e=d(t).text();i.push(e)}}),!i.length){var t=this.$el.find("option:disabled").eq(0);t.length&&""===t[0].value&&i.push(t.text())}this.input.value=i.join(", ")}},{key:"_setSelectedStates",value:function(){for(var t in this._keysSelected={},this._valueDict){var e=this._valueDict[t],i=d(e.el).prop("selected");d(e.optionEl).find('input[type="checkbox"]').prop("checked",i),i?(this._activateOption(d(this.dropdownOptions),d(e.optionEl)),this._keysSelected[t]=!0):d(e.optionEl).removeClass("selected")}}},{key:"_activateOption",value:function(t,e){e&&(this.isMultiple||t.find("li.selected").removeClass("selected"),d(e).addClass("selected"))}},{key:"getSelectedValues",value:function(){var t=[];for(var e in this._keysSelected)t.push(this._valueDict[e].el.value);return t}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_FormSelect}},{key:"defaults",get:function(){return e}}]),n}();M.FormSelect=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"formSelect","M_FormSelect")}(cash),function(s,e){"use strict";var i={},t=function(t){function n(t,e){_classCallCheck(this,n);var i=_possibleConstructorReturn(this,(n.__proto__||Object.getPrototypeOf(n)).call(this,n,t,e));return(i.el.M_Range=i).options=s.extend({},n.defaults,e),i._mousedown=!1,i._setupThumb(),i._setupEventHandlers(),i}return _inherits(n,Component),_createClass(n,[{key:"destroy",value:function(){this._removeEventHandlers(),this._removeThumb(),this.el.M_Range=void 0}},{key:"_setupEventHandlers",value:function(){this._handleRangeChangeBound=this._handleRangeChange.bind(this),this._handleRangeMousedownTouchstartBound=this._handleRangeMousedownTouchstart.bind(this),this._handleRangeInputMousemoveTouchmoveBound=this._handleRangeInputMousemoveTouchmove.bind(this),this._handleRangeMouseupTouchendBound=this._handleRangeMouseupTouchend.bind(this),this._handleRangeBlurMouseoutTouchleaveBound=this._handleRangeBlurMouseoutTouchleave.bind(this),this.el.addEventListener("change",this._handleRangeChangeBound),this.el.addEventListener("mousedown",this._handleRangeMousedownTouchstartBound),this.el.addEventListener("touchstart",this._handleRangeMousedownTouchstartBound),this.el.addEventListener("input",this._handleRangeInputMousemoveTouchmoveBound),this.el.addEventListener("mousemove",this._handleRangeInputMousemoveTouchmoveBound),this.el.addEventListener("touchmove",this._handleRangeInputMousemoveTouchmoveBound),this.el.addEventListener("mouseup",this._handleRangeMouseupTouchendBound),this.el.addEventListener("touchend",this._handleRangeMouseupTouchendBound),this.el.addEventListener("blur",this._handleRangeBlurMouseoutTouchleaveBound),this.el.addEventListener("mouseout",this._handleRangeBlurMouseoutTouchleaveBound),this.el.addEventListener("touchleave",this._handleRangeBlurMouseoutTouchleaveBound)}},{key:"_removeEventHandlers",value:function(){this.el.removeEventListener("change",this._handleRangeChangeBound),this.el.removeEventListener("mousedown",this._handleRangeMousedownTouchstartBound),this.el.removeEventListener("touchstart",this._handleRangeMousedownTouchstartBound),this.el.removeEventListener("input",this._handleRangeInputMousemoveTouchmoveBound),this.el.removeEventListener("mousemove",this._handleRangeInputMousemoveTouchmoveBound),this.el.removeEventListener("touchmove",this._handleRangeInputMousemoveTouchmoveBound),this.el.removeEventListener("mouseup",this._handleRangeMouseupTouchendBound),this.el.removeEventListener("touchend",this._handleRangeMouseupTouchendBound),this.el.removeEventListener("blur",this._handleRangeBlurMouseoutTouchleaveBound),this.el.removeEventListener("mouseout",this._handleRangeBlurMouseoutTouchleaveBound),this.el.removeEventListener("touchleave",this._handleRangeBlurMouseoutTouchleaveBound)}},{key:"_handleRangeChange",value:function(){s(this.value).html(this.$el.val()),s(this.thumb).hasClass("active")||this._showRangeBubble();var t=this._calcRangeOffset();s(this.thumb).addClass("active").css("left",t+"px")}},{key:"_handleRangeMousedownTouchstart",value:function(t){if(s(this.value).html(this.$el.val()),this._mousedown=!0,this.$el.addClass("active"),s(this.thumb).hasClass("active")||this._showRangeBubble(),"input"!==t.type){var e=this._calcRangeOffset();s(this.thumb).addClass("active").css("left",e+"px")}}},{key:"_handleRangeInputMousemoveTouchmove",value:function(){if(this._mousedown){s(this.thumb).hasClass("active")||this._showRangeBubble();var t=this._calcRangeOffset();s(this.thumb).addClass("active").css("left",t+"px"),s(this.value).html(this.$el.val())}}},{key:"_handleRangeMouseupTouchend",value:function(){this._mousedown=!1,this.$el.removeClass("active")}},{key:"_handleRangeBlurMouseoutTouchleave",value:function(){if(!this._mousedown){var t=7+parseInt(this.$el.css("padding-left"))+"px";s(this.thumb).hasClass("active")&&(e.remove(this.thumb),e({targets:this.thumb,height:0,width:0,top:10,easing:"easeOutQuad",marginLeft:t,duration:100})),s(this.thumb).removeClass("active")}}},{key:"_setupThumb",value:function(){this.thumb=document.createElement("span"),this.value=document.createElement("span"),s(this.thumb).addClass("thumb"),s(this.value).addClass("value"),s(this.thumb).append(this.value),this.$el.after(this.thumb)}},{key:"_removeThumb",value:function(){s(this.thumb).remove()}},{key:"_showRangeBubble",value:function(){var t=-7+parseInt(s(this.thumb).parent().css("padding-left"))+"px";e.remove(this.thumb),e({targets:this.thumb,height:30,width:30,top:-30,marginLeft:t,duration:300,easing:"easeOutQuint"})}},{key:"_calcRangeOffset",value:function(){var t=this.$el.width()-15,e=parseFloat(this.$el.attr("max"))||100,i=parseFloat(this.$el.attr("min"))||0;return(parseFloat(this.$el.val())-i)/(e-i)*t}}],[{key:"init",value:function(t,e){return _get(n.__proto__||Object.getPrototypeOf(n),"init",this).call(this,this,t,e)}},{key:"getInstance",value:function(t){return(t.jquery?t[0]:t).M_Range}},{key:"defaults",get:function(){return i}}]),n}();M.Range=t,M.jQueryLoaded&&M.initializeJqueryWrapper(t,"range","M_Range"),t.init(s("input[type=range]"))}(cash,M.anime); \ No newline at end of file diff --git a/scripts/communityModules/notificationCore/notificationCore.js b/scripts/communityModules/notificationCore/notificationCore.js new file mode 100644 index 0000000000..da88ff7c5d --- /dev/null +++ b/scripts/communityModules/notificationCore/notificationCore.js @@ -0,0 +1,164 @@ +"use strict"; +var notificationList = []; + +var sizeData = {30: {widthMul: 1.8, heightMul: 2.05, split: 35, size: 30}}; + +var DEFAULT_SIZE = 30; +var DEFAULT_OFFSET = 10; +var FLOOF_NOTIFICATION_CHANNEL = "Floof-Notif"; + +var offset = DEFAULT_OFFSET; + +init(); + +function init(){ + Messages.messageReceived.connect(messageReceived); +} + +function messageReceived(channel, message, sender, local) { + if (local) { + if (channel === FLOOF_NOTIFICATION_CHANNEL) { + var cmd = {FAILED: true}; + try { + cmd = JSON.parse(message); + } catch (e) { + // + } + if (!cmd.FAILED) { + if (cmd.type === "options") { + if (cmd.offset) { + notificationCore.setOffset(cmd.offset); + } + } else { + notificationCore.add(cmd.text, cmd.sender, cmd.colour); + } + } + } + } +} + +var notificationCore = { + setOffset: function (offsetHeight) { + if (offsetHeight === -1) { + offset = DEFAULT_OFFSET; + } else { + offset = offsetHeight; + } + }, + add: function (text, sender, colour) { + sender = sender ? sender : "NoName"; + colour = colour ? colour : {}; + colour.text = colour.text ? colour.text : {red: 255, green: 255, blue: 255}; + colour.bg = colour.bg ? colour.bg : {red: 10, green: 10, blue: 10}; + var lines = text.split("\n"); + for (var i = lines.length - 1; i >= 0; i--) { + if (i === 0) { + notif("[" + time() + "] " + sender + ": " + lines[i], colour); + } else { + notif(lines[i], colour); + } + } + } +}; + +function time() { + var d = new Date(); + var h = (d.getHours()).toString(); + var m = (d.getMinutes()).toString(); + var s = (d.getSeconds()).toString(); + var h2 = ("0" + h).slice(-2); + var m2 = ("0" + m).slice(-2); + var s2 = ("0" + s).slice(-2); + s2 += (d.getMilliseconds() / 1000).toFixed(2).slice(1); + return h2 + ":" + m2 + ":" + s2; +} + +function findIndex(id) { + var index = -1; + notificationList.forEach(function (noti, i) { + if (noti.id === id) { + index = i; + } + }); + return index; +} + +function cleanUp() { + try { + Messages.messageReceived.disconnect(messageReceived); + } catch (e) { + // empty + } + notificationList.forEach(function (noti) { + Overlays.deleteOverlay(noti.id); + }); +} + +function notif(text, colour) { + + var noti = { + text: " " + text + " ", + time: 10 * 1000, + timeout: null, + timer: null, + fade: null, + colour: colour, + alpha: {text: 1, bg: 0.9} + }; + noti.id = Overlays.addOverlay("text", { + text: '', + font: {size: sizeData[DEFAULT_SIZE].size}, + x: 0, + y: Window.innerHeight, + color: colour.text, + backgroundColor: colour.bg, + backgroundAlpha: noti.alpha.bg, + alpha: noti.alpha.text + }); + + var ts = Overlays.textSize(noti.id, noti.text); + ts.height *= sizeData[DEFAULT_SIZE].heightMul; + ts.width *= sizeData[DEFAULT_SIZE].widthMul; + ts.y = Window.innerHeight - (sizeData[DEFAULT_SIZE].split * (notificationList.length)) - offset; + ts.text = noti.text; + Overlays.editOverlay(noti.id, ts); + + noti.update = function () { + var i = notificationList.length - findIndex(noti.id); + Overlays.editOverlay(noti.id, { + y: Window.innerHeight - (sizeData[DEFAULT_SIZE].split * (i)) - offset + }); + }; + + noti.startFade = function () { + noti.fade = Script.setInterval(noti.fadeOut, 50); + }; + + noti.fadeOut = function () { + noti.alpha.text -= 0.1; + noti.alpha.bg -= 0.1; + Overlays.editOverlay(noti.id, { + alpha: noti.alpha.text, + backgroundAlpha: noti.alpha.bg + }); + + if (Math.max(noti.alpha.text, noti.alpha.bg) <= 0) { + Script.clearInterval(noti.fade); + noti.end(); + } + }; + + noti.end = function () { + Script.clearInterval(noti.timer); + Script.clearTimeout(noti.timeout); + Overlays.deleteOverlay(noti.id); + notificationList.splice(findIndex(noti.id), 1); + }; + + noti.timer = Script.setInterval(noti.update, 10); + noti.timeout = Script.setTimeout(noti.startFade, noti.time); + + notificationList.push(noti); +} + +Script.scriptEnding.connect(cleanUp); \ No newline at end of file diff --git a/scripts/communityScripts/explore/addLocation.html b/scripts/communityScripts/explore/addLocation.html new file mode 100644 index 0000000000..f65c553b9e --- /dev/null +++ b/scripts/communityScripts/explore/addLocation.html @@ -0,0 +1,178 @@ + + + + + + Explore + + + + + + +

    Add Location


    +

    Location List Provider URL

    + + +

    Domain Name

    + + +

    Owner

    + + +

    Port

    +

    + + + + + + + + \ No newline at end of file diff --git a/scripts/communityScripts/explore/bootstrap.min.css b/scripts/communityScripts/explore/bootstrap.min.css new file mode 100644 index 0000000000..882691283a --- /dev/null +++ b/scripts/communityScripts/explore/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.1.3 (https://getbootstrap.com/) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::after,.was-validated .custom-file-input:valid~.custom-file-label::after{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::after,.was-validated .custom-file-input:invalid~.custom-file-label::after{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.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}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.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:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-label::after{border-color:#80bdff}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:2.25rem;padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;padding-left:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:not(:disabled):not(.disabled){cursor:pointer}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{color:#000;text-decoration:none;opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-dialog-centered::before{display:block;height:calc(100vh - (.5rem * 2));content:""}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-dialog-centered::before{height:calc(100vh - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-ms-flex-align:center;align-items:center;width:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-item-next,.carousel-item-prev,.carousel-item.active{transition:none}}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/scripts/communityScripts/explore/bootstrap.min.js b/scripts/communityScripts/explore/bootstrap.min.js new file mode 100644 index 0000000000..00c895f0f3 --- /dev/null +++ b/scripts/communityScripts/explore/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.1.3 (https://getbootstrap.com/) + * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,h){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)P(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
    ',trigger:"hover focus",title:"",delay:0,html:!(Ie={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(Se={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},we="out",Ne={HIDE:"hide"+Ee,HIDDEN:"hidden"+Ee,SHOW:(De="show")+Ee,SHOWN:"shown"+Ee,INSERTED:"inserted"+Ee,CLICK:"click"+Ee,FOCUSIN:"focusin"+Ee,FOCUSOUT:"focusout"+Ee,MOUSEENTER:"mouseenter"+Ee,MOUSELEAVE:"mouseleave"+Ee},Oe="fade",ke="show",Pe=".tooltip-inner",je=".arrow",He="hover",Le="focus",Re="click",xe="manual",We=function(){function i(t,e){if("undefined"==typeof h)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=pe(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(pe(this.getTipElement()).hasClass(ke))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),pe.removeData(this.element,this.constructor.DATA_KEY),pe(this.element).off(this.constructor.EVENT_KEY),pe(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&pe(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===pe(this.element).css("display"))throw new Error("Please use show on visible elements");var t=pe.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){pe(this.element).trigger(t);var n=pe.contains(this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=Fn.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&pe(i).addClass(Oe);var o="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,s=this._getAttachment(o);this.addAttachmentClass(s);var a=!1===this.config.container?document.body:pe(document).find(this.config.container);pe(i).data(this.constructor.DATA_KEY,this),pe.contains(this.element.ownerDocument.documentElement,this.tip)||pe(i).appendTo(a),pe(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new h(this.element,i,{placement:s,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:je},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),pe(i).addClass(ke),"ontouchstart"in document.documentElement&&pe(document.body).children().on("mouseover",null,pe.noop);var l=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,pe(e.element).trigger(e.constructor.Event.SHOWN),t===we&&e._leave(null,e)};if(pe(this.tip).hasClass(Oe)){var c=Fn.getTransitionDurationFromElement(this.tip);pe(this.tip).one(Fn.TRANSITION_END,l).emulateTransitionEnd(c)}else l()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=pe.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==De&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),pe(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(pe(this.element).trigger(i),!i.isDefaultPrevented()){if(pe(n).removeClass(ke),"ontouchstart"in document.documentElement&&pe(document.body).children().off("mouseover",null,pe.noop),this._activeTrigger[Re]=!1,this._activeTrigger[Le]=!1,this._activeTrigger[He]=!1,pe(this.tip).hasClass(Oe)){var o=Fn.getTransitionDurationFromElement(n);pe(n).one(Fn.TRANSITION_END,r).emulateTransitionEnd(o)}else r();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){pe(this.getTipElement()).addClass(Te+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||pe(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(pe(t.querySelectorAll(Pe)),this.getTitle()),pe(t).removeClass(Oe+" "+ke)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?pe(e).parent().is(t)||t.empty().append(e):t.text(pe(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getAttachment=function(t){return Ie[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)pe(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==xe){var e=t===He?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===He?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;pe(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}pe(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||pe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Le:He]=!0),pe(e.getTipElement()).hasClass(ke)||e._hoverState===De?e._hoverState=De:(clearTimeout(e._timeout),e._hoverState=De,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===De&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||pe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),pe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Le:He]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=we,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===we&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=l({},this.constructor.Default,pe(this.element).data(),"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),Fn.typeCheckConfig(ve,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=pe(this.getTipElement()),e=t.attr("class").match(be);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(pe(t).removeClass(Oe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=pe(this).data(ye),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),pe(this).data(ye,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.1.3"}},{key:"Default",get:function(){return Ae}},{key:"NAME",get:function(){return ve}},{key:"DATA_KEY",get:function(){return ye}},{key:"Event",get:function(){return Ne}},{key:"EVENT_KEY",get:function(){return Ee}},{key:"DefaultType",get:function(){return Se}}]),i}(),pe.fn[ve]=We._jQueryInterface,pe.fn[ve].Constructor=We,pe.fn[ve].noConflict=function(){return pe.fn[ve]=Ce,We._jQueryInterface},We),Jn=(qe="popover",Ke="."+(Fe="bs.popover"),Me=(Ue=e).fn[qe],Qe="bs-popover",Be=new RegExp("(^|\\s)"+Qe+"\\S+","g"),Ve=l({},zn.Default,{placement:"right",trigger:"click",content:"",template:''}),Ye=l({},zn.DefaultType,{content:"(string|element|function)"}),ze="fade",Ze=".popover-header",Ge=".popover-body",$e={HIDE:"hide"+Ke,HIDDEN:"hidden"+Ke,SHOW:(Je="show")+Ke,SHOWN:"shown"+Ke,INSERTED:"inserted"+Ke,CLICK:"click"+Ke,FOCUSIN:"focusin"+Ke,FOCUSOUT:"focusout"+Ke,MOUSEENTER:"mouseenter"+Ke,MOUSELEAVE:"mouseleave"+Ke},Xe=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){Ue(this.getTipElement()).addClass(Qe+"-"+t)},r.getTipElement=function(){return this.tip=this.tip||Ue(this.config.template)[0],this.tip},r.setContent=function(){var t=Ue(this.getTipElement());this.setElementContent(t.find(Ze),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(Ge),e),t.removeClass(ze+" "+Je)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=Ue(this.getTipElement()),e=t.attr("class").match(Be);null!==e&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||t + + +image/svg+xml \ No newline at end of file diff --git a/scripts/communityScripts/explore/explore-i.svg b/scripts/communityScripts/explore/explore-i.svg new file mode 100644 index 0000000000..9ea2c45ead --- /dev/null +++ b/scripts/communityScripts/explore/explore-i.svg @@ -0,0 +1,59 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/scripts/communityScripts/explore/explore.html b/scripts/communityScripts/explore/explore.html new file mode 100644 index 0000000000..affaf0887f --- /dev/null +++ b/scripts/communityScripts/explore/explore.html @@ -0,0 +1,188 @@ + + + + + + Explore + + + + + + +

    Explore

    + + + + + +

    + +

    + + + + + + + + diff --git a/scripts/communityScripts/explore/explore.js b/scripts/communityScripts/explore/explore.js new file mode 100644 index 0000000000..ac1de51521 --- /dev/null +++ b/scripts/communityScripts/explore/explore.js @@ -0,0 +1,159 @@ +// explore.js +// +// Created by Darlingnotin in 2019. +// Copyright 2019 Darlingnotin +// +// App maintained in: https://github.com/kasenvr/Decentralized_GoTo_Experimental +// App copied to: https://github.com/kasenvr/project-athena +// +// Distributed under the ISC license. +// See the accompanying file LICENSE or https://opensource.org/licenses/ISC + +(function () { + var defaultGoToJSON = "https://metaverse.vircadia.com/interim/d-goto/app/goto.json"; + + var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + Menu.menuItemEvent.connect(onMenuItemEvent); + var AppUi = Script.require('appUi'); + var goToAddresses; + var permission; + Menu.addMenu("Explore"); + Menu.addMenuItem("Explore", "Subscribe to new GoTo provider"); + Menu.addMenu("Explore > Unsubscribe from GoTo provider"); + var goToAddress = Settings.getValue("goToDecentral", ""); + for (var i = 0; i < goToAddress.length; i++) { + Menu.addMenuItem("Explore > Unsubscribe from GoTo provider", goToAddress[i]); + } + var ui; + function startup() { + goToAddress = Settings.getValue("goToDecentral", ""); + if (goToAddress == "") { + var initialGoToList = Script.resolvePath(defaultGoToJSON); + Menu.addMenuItem("Explore > Unsubscribe from GoTo provider", initialGoToList); + goToAddressNow = [ + initialGoToList + ]; + Settings.setValue("goToDecentral", goToAddressNow); + } + + var scriptDir = Script.resolvePath(""); + scriptDir = scriptDir.slice(0, scriptDir.lastIndexOf("/") + 1); + + ui = new AppUi({ + buttonName: "EXPLORE", + home: Script.resolvePath("explore.html"), + graphicsDirectory: scriptDir + }); + } + + function onWebEventReceived(event) { + messageData = JSON.parse(event); + if (messageData.action == "requestAddressList") { + goToAddresses = Settings.getValue("goToDecentral", ""); + for (var i = 0; i < goToAddresses.length; i++) { + + try { + Script.require(goToAddresses[i] + "?" + Date.now()); + } + catch (e) { + goToAddresses.remove(goToAddresses[i]); + } + } + var children = goToAddresses + .map(function (url) { return Script.require(url + '?' + Date.now()); }) + .reduce(function (result, someChildren) { return result.concat(someChildren); }, []); + + for (var z = 0; z < children.length; z++) { + delete children[z].age; + delete children[z].id; + children[z]["Domain Name"] = children[z]["Domain Name"].replace(//g, '<'); + children[z].Owner = children[z].Owner.replace(//g, '<'); + } + + permission = Entities.canRez() + + var readyEvent = { + "action": "addressList", + "myAddress": children, + "permission": permission + }; + + tablet.emitScriptEvent(JSON.stringify(readyEvent)); + + } else if (messageData.action == "goToUrl") { + Window.location = messageData.visit; + } else if (messageData.action == "addLocation") { + + var locationBoxUserData = { + owner: messageData.owner, + domainName: messageData.domainName, + port: messageData.Port, + grabbableKey: { + grabbable: false + } + }; + + var locationBoxName = "Explore Marker (" + messageData.domainName + ")"; + + locationboxID = Entities.addEntity({ + position: Vec3.sum(MyAvatar.position, Quat.getFront(MyAvatar.orientation)), + userData: JSON.stringify(locationBoxUserData), + serverScripts: messageData.script, + color: { red: 255, green: 0, blue: 0 }, + type: "Box", + name: locationBoxName, + collisionless: true, + grabbable: false + }); + } else if (messageData.action == "retrievePortInformation") { + var readyEvent = { + "action": "retrievePortInformationResponse", + "goToAddresses": goToAddresses + }; + + tablet.emitScriptEvent(JSON.stringify(readyEvent)); + + } + } + + function onMenuItemEvent(menuItem) { + var menuItemList = JSON.stringify(Settings.getValue("goToDecentral", "")); + var menuItemExists = menuItemList.indexOf(menuItem) !== -1; + if (menuItem == "Subscribe to new GoTo provider") { + goToAddress = Settings.getValue("goToDecentral", ""); + var arrayLength = goToAddress.length; + var prom = Window.prompt("Enter URL to GoTo JSON.", ""); + if (prom) { + goToAddress[arrayLength] = prom; + Settings.setValue("goToDecentral", goToAddress); + Menu.addMenuItem("Explore > Unsubscribe from GoTo provider", prom); + } + } else if (menuItemExists) { + goToAddresses = Settings.getValue("goToDecentral", ""); + Menu.removeMenuItem("Explore > Unsubscribe from GoTo provider", menuItem); + goToAddresses.remove(menuItem); + Settings.setValue("goToDecentral", goToAddresses); + } + } + + Array.prototype.remove = function () { + var what, a = arguments, L = a.length, ax; + while (L && this.length) { + what = a[--L]; + while ((ax = this.indexOf(what)) !== -1) { + this.splice(ax, 1); + } + } + return this; + }; + + tablet.webEventReceived.connect(onWebEventReceived); + startup(); + + Script.scriptEnding.connect(function () { + Messages.unsubscribe("goTo"); + Menu.removeMenu("Explore"); + tablet.webEventReceived.disconnect(onWebEventReceived); + Menu.menuItemEvent.disconnect(onMenuItemEvent); + }); +}()); diff --git a/scripts/communityScripts/explore/explore.svg b/scripts/communityScripts/explore/explore.svg new file mode 100644 index 0000000000..7033f3149e --- /dev/null +++ b/scripts/communityScripts/explore/explore.svg @@ -0,0 +1,260 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scripts/communityScripts/explore/fancyTable.js b/scripts/communityScripts/explore/fancyTable.js new file mode 100644 index 0000000000..225baf24de --- /dev/null +++ b/scripts/communityScripts/explore/fancyTable.js @@ -0,0 +1,217 @@ +/*! + * jQuery fancyTable plugin + * https://github.com/myspace-nu + * + * Copyright 2018 Johan Johansson + * Released under the MIT license + */ +(function($) { + $.fn.fancyTable = function(options) { + var settings = $.extend({ + inputStyle: "", + inputPlaceholder: "Search...", + pagination: false, + paginationClass: "btn btn-light", + paginationClassActive: "active", + pagClosest: 3, + perPage: 10, + sortable: true, + searchable: true, + onInit: function(){ }, + onUpdate: function(){ }, + testing: false + }, options); + var instance = this; + this.settings = settings; + this.tableUpdate = function (elm) { + elm.fancyTable.matches = 0; + $(elm).find("tbody tr").each(function() { + var n=0; + var match = true; + var globalMatch = false; + $(this).find("td").each(function() { + if(!settings.globalSearch && elm.fancyTable.searchArr[n] && !(new RegExp(elm.fancyTable.searchArr[n],"i").test($(this).html()))){ + match = false; + } else if(settings.globalSearch && (!elm.fancyTable.search || (new RegExp(elm.fancyTable.search,"i").test($(this).html())))){ + if(!Array.isArray(settings.globalSearchExcludeColumns) || !settings.globalSearchExcludeColumns.includes(n+1)){ + globalMatch = true; + } + } + n++; + }); + if((settings.globalSearch && globalMatch) || (!settings.globalSearch && match)){ + elm.fancyTable.matches++ + if(!settings.pagination || (elm.fancyTable.matches>(elm.fancyTable.perPage*(elm.fancyTable.page-1)) && elm.fancyTable.matches<=(elm.fancyTable.perPage*elm.fancyTable.page))){ + $(this).show(); + } else { + $(this).hide(); + } + } else { + $(this).hide(); + } + }); + elm.fancyTable.pages = Math.ceil(elm.fancyTable.matches/elm.fancyTable.perPage); + if(settings.pagination){ + var paginationElement = (elm.fancyTable.paginationElement) ? $(elm.fancyTable.paginationElement) : $(elm).find(".pag"); + paginationElement.empty(); + for(var n=1; n<=elm.fancyTable.pages; n++){ + if(n==1 || (n>(elm.fancyTable.page-(settings.pagClosest+1)) && n<(elm.fancyTable.page+(settings.pagClosest+1))) || n==elm.fancyTable.pages){ + var a = $("",{ + html:n, + "data-n": n, + style:"margin:0.2em", + class:settings.paginationClass+" "+((n==elm.fancyTable.page)?settings.paginationClassActive:"") + }).css("cursor","pointer").bind("click",function(){ + elm.fancyTable.page = $(this).data("n"); + instance.tableUpdate(elm); + }); + if(n==elm.fancyTable.pages && elm.fancyTable.page<(elm.fancyTable.pages-settings.pagClosest-1)){ + paginationElement.append($("...")); + } + paginationElement.append(a); + if(n==1 && elm.fancyTable.page>settings.pagClosest+2){ + paginationElement.append($("...")); + } + } + } + } + settings.onUpdate.call(this,elm); + }; + this.reinit = function(elm){ + $(this).each(function(){ + $(this).find("th a").contents().unwrap(); + $(this).find("tr.fancySearchRow").remove(); + }); + $(this).fancyTable(this.settings); + }; + this.tableSort = function (elm) { + if(typeof elm.fancyTable.sortColumn !== "undefined" && elm.fancyTable.sortColumn < elm.fancyTable.nColumns){ + $(elm).find("thead th div.sortArrow").each(function(){ + $(this).remove(); + }); + var sortArrow = $("
    ",{"class":"sortArrow"}).css({"margin":"0.1em","display":"inline-block","width":0,"height":0,"border-left":"0.4em solid transparent","border-right":"0.4em solid transparent"}); + sortArrow.css( + (elm.fancyTable.sortOrder>0) ? + {"border-top":"0.4em solid #000"} : + {"border-bottom":"0.4em solid #000"} + ); + $(elm).find("thead th a").eq(elm.fancyTable.sortColumn).append(sortArrow); + var rows = $(elm).find("tbody tr").toArray().sort( + function(a, b) { + var stra = $(a).find("td").eq(elm.fancyTable.sortColumn).html(); + var strb = $(b).find("td").eq(elm.fancyTable.sortColumn).html(); + if(elm.fancyTable.sortAs[elm.fancyTable.sortColumn] == 'numeric'){ + return((elm.fancyTable.sortOrder>0) ? parseFloat(stra)-parseFloat(strb) : parseFloat(strb)-parseFloat(stra)); + } else { + return((strastrb)?elm.fancyTable.sortOrder:0); + } + } + ); + $(elm).find("tbody").empty().append(rows); + } + }; + this.each(function() { + if($(this).prop("tagName")!=="TABLE"){ + console.warn("fancyTable: Element is not a table."); + return true; + } + var elm = this; + elm.fancyTable = { + nColumns: $(elm).find("td").first().parent().find("td").length, + nRows : $(this).find("tbody tr").length, + perPage : settings.perPage, + page : 1, + pages : 0, + matches : 0, + searchArr : [], + search : "", + sortColumn : settings.sortColumn, + sortOrder : (typeof settings.sortOrder === "undefined") ? 1 : (new RegExp("desc","i").test(settings.sortOrder) || settings.sortOrder == -1) ? -1 : 1, + sortAs:[], // undefined or numeric + paginationElement : settings.paginationElement + }; + if($(elm).find("tbody").length==0){ + var content = $(elm).html(); + $(elm).empty(); + $(elm).append("").append($(content)); + } + if($(elm).find("thead").length==0){ + $(elm).prepend($("")); + // Maybe add generated headers at some point + //var c=$(elm).find("tr").first().find("td").length; + //for(var n=0; n")); + //} + } + if(settings.sortable){ + var n=0; + $(elm).find("thead th").each(function() { + elm.fancyTable.sortAs.push(($(this).data('sortas')=='numeric')?'numeric':''); + var content = $(this).html(); + var a = $("",{ + html:content, + "data-n": n, + class:"" + }).css("cursor","pointer").bind("click",function(){ + if(elm.fancyTable.sortColumn == $(this).data("n")){ + elm.fancyTable.sortOrder=-elm.fancyTable.sortOrder; + } else { + elm.fancyTable.sortOrder=1; + } + elm.fancyTable.sortColumn = $(this).data("n"); + instance.tableSort(elm); + instance.tableUpdate(elm); + }); + $(this).empty(); + $(this).append(a); + n++; + }); + } + if(settings.searchable){ + var searchHeader = $("").addClass("fancySearchRow"); + if(settings.globalSearch){ + var searchField = $("",{ + "placeholder": settings.inputPlaceholder, + style:"width:100%;"+settings.inputStyle + }).bind("change paste keyup",function(){ + elm.fancyTable.search = $(this).val(); + elm.fancyTable.page = 1; + instance.tableUpdate(elm); + }); + var th = $("",{ style:"padding:2px;" }).attr("colspan",elm.fancyTable.nColumns); + $(searchField).appendTo($(th)); + $(th).appendTo($(searchHeader)); + } else { + var n=0; + $(elm).find("td").first().parent().find("td").each(function() { + elm.fancyTable.searchArr.push(""); + var searchField = $("",{ + "data-n": n, + "placeholder": settings.inputPlaceholder, + style:"width:100%;"+settings.inputStyle + }).bind("change paste keyup",function(){ + elm.fancyTable.searchArr[$(this).data("n")] = $(this).val(); + elm.fancyTable.page = 1; + instance.tableUpdate(elm); + }); + var th = $("",{ style:"padding:2px;" }); + $(searchField).appendTo($(th)); + $(th).appendTo($(searchHeader)); + n++; + }); + } + searchHeader.appendTo($(elm).find("thead")); + } + // Sort + instance.tableSort(elm); + if(settings.pagination && !settings.paginationElement){ + $(elm).find("tfoot").remove(); + $(elm).append($("")); + $(elm).find("tfoot tr").append($("",{ }).attr("colspan",elm.fancyTable.nColumns)); + } + instance.tableUpdate(elm); + settings.onInit.call(this,elm); + }); + return this; + }; +}(jQuery)); \ No newline at end of file diff --git a/scripts/communityScripts/explore/jquery.min.js b/scripts/communityScripts/explore/jquery.min.js new file mode 100644 index 0000000000..4d9b3a2587 --- /dev/null +++ b/scripts/communityScripts/explore/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w(" + + + + + + +
    + Add more functionalities...
    + + + + + +
    + + + + + +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +

    Want to contribute and add your own app?
    + Read the guide!

    + + + diff --git a/scripts/system/more/plus-16.png b/scripts/system/more/plus-16.png new file mode 100644 index 0000000000..6935847757 Binary files /dev/null and b/scripts/system/more/plus-16.png differ diff --git a/scripts/system/more/search-32.png b/scripts/system/more/search-32.png new file mode 100644 index 0000000000..8d4bb5daa2 Binary files /dev/null and b/scripts/system/more/search-32.png differ diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js index 94117fd9ea..8c048cc0cc 100644 --- a/scripts/system/tablet-goto.js +++ b/scripts/system/tablet-goto.js @@ -9,6 +9,7 @@ // // Created by Dante Ruiz on 8 February 2017 // Copyright 2016 High Fidelity, Inc. +// Copyright 2020 Project Athena contributors. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -106,7 +107,7 @@ function isReturnedDataEmpty(data) { var ui; var GOTO_QML_SOURCE = "hifi/tablet/TabletAddressDialog.qml"; -var BUTTON_NAME = "GOTO"; +var BUTTON_NAME = "OLD GOTO"; function startup() { var options = [ 'include_actions=announcement', @@ -119,6 +120,8 @@ function startup() { ui = new AppUi({ buttonName: BUTTON_NAME, + normalButton: "icons/tablet-icons/goto-i.svg", + activeButton: "icons/tablet-icons/goto-a.svg", sortOrder: 8, onOpened: gotoOpened, home: GOTO_QML_SOURCE, diff --git a/server-console/package.json b/server-console/package.json index 6824d1d9cf..ed01a9c89e 100644 --- a/server-console/package.json +++ b/server-console/package.json @@ -1,6 +1,6 @@ { - "name": "HighFidelityConsole", - "description": "High Fidelity Console", + "name": "VircadiaConsole", + "description": "Vircadia Console", "author": "High Fidelity", "license": "Apache-2.0", "version": "1.0.0", @@ -13,7 +13,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/highfidelity/hifi.git" + "url": "https://github.com/kasenvr/project-athena.git" }, "main": "src/main.js", "scripts": { diff --git a/server-console/packager.js b/server-console/packager.js index 60aff6c540..dadc306bbf 100644 --- a/server-console/packager.js +++ b/server-console/packager.js @@ -28,15 +28,15 @@ var options = { const EXEC_NAME = "server-console"; var SHORT_NAME = argv.client_only ? "Console" : "Sandbox"; -var FULL_NAME = argv.client_only ? "High Fidelity Console" : "High Fidelity Sandbox"; +var FULL_NAME = argv.client_only ? "Vircadia Console" : "Vircadia Sandbox"; // setup per OS options if (osType == "Darwin") { - options["app-bundle-id"] = "com.highfidelity.server-console" + (argv.production ? "" : "-dev") + options["app-bundle-id"] = "com.vircadia.server-console" + (argv.production ? "" : "-dev") options["name"] = SHORT_NAME } else if (osType == "Windows_NT") { options["version-string"] = { - CompanyName: "High Fidelity, Inc.", + CompanyName: "Vircadia", FileDescription: FULL_NAME, ProductName: FULL_NAME, OriginalFilename: EXEC_NAME + ".exe" diff --git a/server-console/resources/console-beta.icns b/server-console/resources/console-beta.icns index 0023636e39..1fe162f88e 100644 Binary files a/server-console/resources/console-beta.icns and b/server-console/resources/console-beta.icns differ diff --git a/server-console/resources/console-beta.ico b/server-console/resources/console-beta.ico index 9263623fb4..63a3eff482 100644 Binary files a/server-console/resources/console-beta.ico and b/server-console/resources/console-beta.ico differ diff --git a/server-console/resources/console-beta.png b/server-console/resources/console-beta.png index 3494a6ef8f..59fe03c8ee 100644 Binary files a/server-console/resources/console-beta.png and b/server-console/resources/console-beta.png differ diff --git a/server-console/resources/console-notification.png b/server-console/resources/console-notification.png index b7df5312e3..e8991cd773 100644 Binary files a/server-console/resources/console-notification.png and b/server-console/resources/console-notification.png differ diff --git a/server-console/resources/console-tray-osx-stopped.png b/server-console/resources/console-tray-osx-stopped.png index 53589b60b0..82fcf76d5c 100644 Binary files a/server-console/resources/console-tray-osx-stopped.png and b/server-console/resources/console-tray-osx-stopped.png differ diff --git a/server-console/resources/console-tray-osx-stopped@2x.png b/server-console/resources/console-tray-osx-stopped@2x.png index 5356afb93e..535e6b8135 100644 Binary files a/server-console/resources/console-tray-osx-stopped@2x.png and b/server-console/resources/console-tray-osx-stopped@2x.png differ diff --git a/server-console/resources/console-tray-osx-stopping.png b/server-console/resources/console-tray-osx-stopping.png index 3255d43f60..c99313d00b 100644 Binary files a/server-console/resources/console-tray-osx-stopping.png and b/server-console/resources/console-tray-osx-stopping.png differ diff --git a/server-console/resources/console-tray-osx-stopping@2x.png b/server-console/resources/console-tray-osx-stopping@2x.png index f8fb805350..de09b722d3 100644 Binary files a/server-console/resources/console-tray-osx-stopping@2x.png and b/server-console/resources/console-tray-osx-stopping@2x.png differ diff --git a/server-console/resources/console-tray-osx.png b/server-console/resources/console-tray-osx.png index 11dbbbc38f..36756dd16f 100644 Binary files a/server-console/resources/console-tray-osx.png and b/server-console/resources/console-tray-osx.png differ diff --git a/server-console/resources/console-tray-osx@2x.png b/server-console/resources/console-tray-osx@2x.png index 8acd094606..86d9eacea2 100644 Binary files a/server-console/resources/console-tray-osx@2x.png and b/server-console/resources/console-tray-osx@2x.png differ diff --git a/server-console/resources/console-tray-stopped.ico b/server-console/resources/console-tray-stopped.ico index 8921a80297..2f0251a185 100644 Binary files a/server-console/resources/console-tray-stopped.ico and b/server-console/resources/console-tray-stopped.ico differ diff --git a/server-console/resources/console-tray-win-stopped.png b/server-console/resources/console-tray-win-stopped.png index 033ca3dfa4..cedc6e02e1 100644 Binary files a/server-console/resources/console-tray-win-stopped.png and b/server-console/resources/console-tray-win-stopped.png differ diff --git a/server-console/resources/console-tray-win-stopped@2x.png b/server-console/resources/console-tray-win-stopped@2x.png index e3d8de7aaa..b176209758 100644 Binary files a/server-console/resources/console-tray-win-stopped@2x.png and b/server-console/resources/console-tray-win-stopped@2x.png differ diff --git a/server-console/resources/console-tray-win-stopping.png b/server-console/resources/console-tray-win-stopping.png index 860bddbd3e..ddf60efc8e 100644 Binary files a/server-console/resources/console-tray-win-stopping.png and b/server-console/resources/console-tray-win-stopping.png differ diff --git a/server-console/resources/console-tray-win-stopping@2x.png b/server-console/resources/console-tray-win-stopping@2x.png index 46e5e32f59..50f9df457f 100644 Binary files a/server-console/resources/console-tray-win-stopping@2x.png and b/server-console/resources/console-tray-win-stopping@2x.png differ diff --git a/server-console/resources/console-tray-win.png b/server-console/resources/console-tray-win.png index 6ff889828c..cd8fa1d691 100644 Binary files a/server-console/resources/console-tray-win.png and b/server-console/resources/console-tray-win.png differ diff --git a/server-console/resources/console-tray-win@2x.png b/server-console/resources/console-tray-win@2x.png index 7295647c20..142498f6a1 100644 Binary files a/server-console/resources/console-tray-win@2x.png and b/server-console/resources/console-tray-win@2x.png differ diff --git a/server-console/resources/console-tray.ico b/server-console/resources/console-tray.ico index becc1b8e8b..6f06b43f73 100644 Binary files a/server-console/resources/console-tray.ico and b/server-console/resources/console-tray.ico differ diff --git a/server-console/resources/console.icns b/server-console/resources/console.icns index 38a7cc5b64..1fe162f88e 100644 Binary files a/server-console/resources/console.icns and b/server-console/resources/console.icns differ diff --git a/server-console/resources/console.ico b/server-console/resources/console.ico index a3957ea0eb..63a3eff482 100644 Binary files a/server-console/resources/console.ico and b/server-console/resources/console.ico differ diff --git a/server-console/resources/console.png b/server-console/resources/console.png index 0cd3b0a3c0..e6e13081fd 100644 Binary files a/server-console/resources/console.png and b/server-console/resources/console.png differ diff --git a/server-console/src/content-update.html b/server-console/src/content-update.html index 9298cd53e6..7c6b4c9971 100644 --- a/server-console/src/content-update.html +++ b/server-console/src/content-update.html @@ -1,7 +1,7 @@ - High Fidelity Sandbox + Vircadia Sandbox @@ -45,7 +45,7 @@
    diff --git a/server-console/src/downloader.html b/server-console/src/downloader.html index 07d3392246..f1f7a2024c 100644 --- a/server-console/src/downloader.html +++ b/server-console/src/downloader.html @@ -1,7 +1,7 @@ - High Fidelity + Vircadia diff --git a/server-console/src/images/console-hf-logo-2x.png b/server-console/src/images/console-hf-logo-2x.png index 420fb18fde..e8b048fae0 100644 Binary files a/server-console/src/images/console-hf-logo-2x.png and b/server-console/src/images/console-hf-logo-2x.png differ diff --git a/server-console/src/main.js b/server-console/src/main.js index 5adb4be4cb..d8d6fea4bf 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -113,7 +113,7 @@ function isInterfaceInstalled () { // the executable to a random location before starting it // which makes finding the interface near impossible using // relative paths. For now, as there are no server-only - // installs, we just assume the interface is installed here + // installs, we just assume the interface is installed here return true; } else { return interfacePath; @@ -134,7 +134,7 @@ function shutdown() { dialog.showMessageBox({ type: 'question', buttons: ['Yes', 'No'], - title: 'Stopping High Fidelity Sandbox', + title: 'Stopping Vircadia Sandbox', message: 'Quitting will stop your Sandbox and your Home domain will no longer be running.\nDo you wish to continue?' }, shutdownCallback); } else { @@ -280,7 +280,7 @@ function binaryMissingMessage(displayName, executableName, required) { var message = "The " + displayName + " executable was not found.\n"; if (required) { - message += "It is required for the High Fidelity Sandbox to run.\n\n"; + message += "It is required for the Vircadia Sandbox to run.\n\n"; } else { message += "\n"; } @@ -293,7 +293,7 @@ function binaryMissingMessage(displayName, executableName, required) { message += paths.join("\n"); } else { message += "It is expected to be found beside this executable.\n"; - message += "You may need to re-install the High Fidelity Sandbox."; + message += "You may need to re-install the Vircadia Sandbox."; } return message; @@ -337,10 +337,10 @@ var notificationState = NotificationState.UNNOTIFIED; function setNotificationState (notificationType, pending = undefined) { if (pending !== undefined) { - if ((notificationType === HifiNotificationType.TRANSACTIONS || + if ((notificationType === HifiNotificationType.TRANSACTIONS || notificationType === HifiNotificationType.ITEMS)) { // special case, because we want to clear the indicator light - // on INVENTORY when either Transactions or Items are + // on INVENTORY when either Transactions or Items are // clicked on in the notification popup, we detect that case // here and force both to be unnotified. pendingNotifications[HifiNotificationType.TRANSACTIONS] = pending; @@ -399,7 +399,7 @@ function visitSandboxClicked() { StartInterface('hifi://localhost'); } else { // show an error to say that we can't go home without an interface instance - dialog.showErrorBox("Client Not Found", binaryMissingMessage("High Fidelity client", "Interface", false)); + dialog.showErrorBox("Client Not Found", binaryMissingMessage("Vircadia client", "Interface", false)); } } @@ -613,7 +613,7 @@ function updateTrayMenu(serverState) { tray.setImage(trayIcons[notificationState]); tray.setContextMenu(Menu.buildFromTemplate(menuArray)); if (isShuttingDown) { - tray.setToolTip('High Fidelity - Shutting Down'); + tray.setToolTip('Vircadia - Shutting Down'); } } } @@ -868,7 +868,7 @@ function onContentLoaded() { notifier.notify({ icon: notificationIcon, title: 'An update is available!', - message: 'High Fidelity version ' + latestVersion + ' is available', + message: 'Vircadia version ' + latestVersion + ' is available', wait: true, appID: buildInfo.appUserModelId, url: url @@ -941,7 +941,7 @@ app.on('ready', function() { // Create tray icon tray = new Tray(trayIcons[NotificationState.UNNOTIFIED]); - tray.setToolTip('High Fidelity'); + tray.setToolTip('Vircadia'); tray.on('click', function() { tray.popUpContextMenu(tray.menu); @@ -951,7 +951,7 @@ app.on('ready', function() { trayNotifications.startPolling(); } updateTrayMenu(ProcessGroupStates.STOPPED); - + if (isServerInstalled()) { maybeInstallDefaultContentSet(onContentLoaded); } diff --git a/server-console/src/modules/hf-app.js b/server-console/src/modules/hf-app.js index af6c38cdb3..cdb744e5e6 100644 --- a/server-console/src/modules/hf-app.js +++ b/server-console/src/modules/hf-app.js @@ -34,8 +34,8 @@ exports.getBuildInfo = function() { buildIdentifier: "dev", buildNumber: "0", stableBuild: "0", - organization: "High Fidelity - dev", - appUserModelId: "com.highfidelity.console" + organization: "Vircadia - dev", + appUserModelId: "com.vircadia.console" }; var buildInfo = DEFAULT_BUILD_INFO; @@ -63,11 +63,11 @@ exports.startInterface = function(url) { // do this as a workaround for app translocation on osx, which makes // it nearly impossible to find the interface executable - var bundle_id = 'com.highfidelity.interface-dev'; + var bundle_id = 'com.vircadia.interface-dev'; if (buildInfo.releaseType == 'PR') { - bundle_id = 'com.highfidelity.interface-pr'; + bundle_id = 'com.vircadia.interface-pr'; } else if (buildInfo.releaseType == 'PRODUCTION') { - bundle_id = 'com.highfidelity.interface'; + bundle_id = 'com.vircadia.interface'; } childProcess.exec('open -b ' + bundle_id + ' --args --url ' + url); } else { diff --git a/server-console/src/splash.html b/server-console/src/splash.html index d93b742181..f273ef16b7 100644 --- a/server-console/src/splash.html +++ b/server-console/src/splash.html @@ -1,7 +1,7 @@ - High Fidelity + Vircadia @@ -19,7 +19,7 @@

    What now?

    -High Fidelity is now installed and your Home domain is ready for you to explore. To start you off, we've put a few things in your home to play around with and learn the ropes. +Vircadia is now installed and your Home domain is ready for you to explore. To start you off, we've put a few things in your home to play around with and learn the ropes.

    @@ -28,13 +28,13 @@ You can make your home yours by uploading your own models and scripts.

    - To get started exploring and creating, check out our Quick-start Guide + To get started exploring and creating, check out our Quick-start Guide

    How do I use it?

    - You can manage your server by clicking on the High Fidelity icon in your + You can manage your server by clicking on the Vircadia icon in your + + + + + + + + + + + + + - - - - + +
    + +
    +

    @@ -70,7 +134,43 @@ + + + + + + diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js index 496b144218..3c1ec08bb0 100644 --- a/tools/jsdoc/plugins/hifi.js +++ b/tools/jsdoc/plugins/hifi.js @@ -16,7 +16,7 @@ exports.handlers = { beforeParse: function(e) { var pathTools = require('path'); var rootFolder = pathTools.dirname(e.filename); - console.log("Scanning hifi source for jsdoc comments..."); + console.log("Scanning the Vircadia source for JSDoc comments..."); // directories to scan for jsdoc comments var dirList = [ diff --git a/tools/nitpick/AppDataHighFidelity/Interface.json b/tools/nitpick/AppDataHighFidelity/Interface.json index 7a8a15e002..5991ed64aa 100644 --- a/tools/nitpick/AppDataHighFidelity/Interface.json +++ b/tools/nitpick/AppDataHighFidelity/Interface.json @@ -279,5 +279,6 @@ "toolbar/com.highfidelity.interface.toolbar.system/x": 655, "toolbar/com.highfidelity.interface.toolbar.system/y": 953, "toolbar/constrainToolbarToCenterX": true, + "private/selectedMetaverseURL": "https://metaverse.highfidelity.com", "wallet/autoLogout": true }