diff --git a/.env b/.env new file mode 100644 index 0000000..ac3ce33 --- /dev/null +++ b/.env @@ -0,0 +1,14 @@ +FEDERATED_CODE_HOST=127.0.0.1 +FEDERATED_CODE_PORT=8000 +FEDERATED_CODE_DOMAIN=${FEDERATED_CODE_HOST}:${FEDERATED_CODE_PORT} + +POSTGRES_HOST=127.0.0.1 +POSTGRES_DB=federatedcode +POSTGRES_USER=federatedcode +POSTGRES_PASSWORD=federatedcode + +FEDERATED_CODE_GIT_PATH=/home/ziad/new_vul +FEDERATED_CODE_CLIENT_ID=4SDoNYvLfOG2h8LNt1ksIwZ4BSx8fZPmPar8SXKJ +FEDERATED_CODE_CLIENT_SECRET=OrzhuzFcxeoaQ8wf1kXPyczmsh6DL10A3duTz1CuSxktvAxKlsjjiGqWUafbovZip75Kt7GmHIOouveRDER7bc41IVq29SvnTqUkFtJKCXcYArQf7WY3BiSPEOBwlw5F +FEDERATED_CODE_STATIC_ROOT=/var/federatedcode/static/ +STATIC_ROOT=/var/federatedcode/static/ \ No newline at end of file diff --git a/.github/workflows/docs-ci.yml b/.github/workflows/docs-ci.yml index ada779b..68133cf 100644 --- a/.github/workflows/docs-ci.yml +++ b/.github/workflows/docs-ci.yml @@ -7,7 +7,6 @@ jobs: runs-on: ubuntu-20.04 strategy: - max-parallel: 4 matrix: python-version: [3.9] diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..141d9e3 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,51 @@ +name: run tests + +on: [push, pull_request] + +env: + FEDERATED_CODE_HOST: 127.0.0.1 + FEDERATED_CODE_PORT: 8000 + FEDERATED_CODE_DOMAIN: 127.0.0.1:8000 + POSTGRES_HOST: 127.0.0.1 + POSTGRES_DB: federatedcode + POSTGRES_USER: federatedcode + POSTGRES_PASSWORD: federatedcode + +jobs: + build: + runs-on: ubuntu-20.04 + + services: + postgres: + image: postgres:latest + env: + POSTGRES_DB: ${{ env.POSTGRES_DB }} + POSTGRES_USER: ${{ env.POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }} + ports: + - 5432:5432 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install dependencies + run: make dev + + - name: Run tests + run: make test + env: + GH_TOKEN: 1 + FEDERATED_CODE_HOST: ${{ env.FEDERATED_CODE_HOST }} + FEDERATED_CODE_PORT: ${{ env.FEDERATED_CODE_PORT }} + FEDERATED_CODE_DOMAIN: ${{ env.FEDERATED_CODE_DOMAIN }} + POSTGRES_HOST: ${{ env.POSTGRES_HOST }} + POSTGRES_DB: ${{ env.POSTGRES_DB }} + POSTGRES_USER: ${{ env.POSTGRES_USER }} + POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }} + POSTGRES_PORT: ${{ env.POSTGRES_PORT }} diff --git a/.gitignore b/.gitignore index 2d48196..8dd2d47 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,4 @@ tcl # Ignore Jupyter Notebook related temp files .ipynb_checkpoints/ +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f5dd36b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +FROM python:3.10 +# Python settings: Force unbuffered stdout and stderr (i.e. they are flushed to terminal immediately) +ENV PYTHONUNBUFFERED 1 +# Python settings: do not write pyc files +ENV PYTHONDONTWRITEBYTECODE 1 + +RUN pip install --upgrade pip + +WORKDIR /federatedcode + +COPY requirements.txt pyproject.toml /federatedcode/ + +RUN pip install -r requirements.txt + +COPY . /federatedcode \ No newline at end of file diff --git a/Makefile b/Makefile index cc36c35..5e5fd71 100644 --- a/Makefile +++ b/Makefile @@ -7,23 +7,39 @@ # See https://github.com/nexB/skeleton for support or download. # See https://aboutcode.org for more information about nexB OSS projects. # +include .env # Python version can be specified with `$ PYTHON_EXE=python3.x make conf` PYTHON_EXE?=python3 VENV=venv ACTIVATE?=. ${VENV}/bin/activate; +MANAGE=${VENV}/bin/python manage.py + +# Use sudo for postgres, but only on Linux +UNAME := $(shell uname) +ifeq ($(UNAME), Linux) + SUDO_POSTGRES=sudo -u postgres +else + SUDO_POSTGRES= +endif dev: @echo "-> Configure the development envt." ./configure --dev +envfile: + @echo "-> Create the .env file and generate a secret key" + @if test -f ${ENV_FILE}; then echo ".env file exists already"; exit 1; fi + @mkdir -p $(shell dirname ${ENV_FILE}) && touch ${ENV_FILE} + @echo SECRET_KEY=\"${GET_SECRET_KEY}\" > ${ENV_FILE} + isort: @echo "-> Apply isort changes to ensure proper imports ordering" - ${VENV}/bin/isort --sl -l 100 src tests setup.py + ${VENV}/bin/isort --sl -l 100 tests setup.py black: @echo "-> Apply black code formatter" - ${VENV}/bin/black -l 100 src tests setup.py + ${VENV}/bin/black -l 100 tests setup.py doc8: @echo "-> Run doc8 validation" @@ -35,9 +51,9 @@ check: @echo "-> Run pycodestyle (PEP8) validation" @${ACTIVATE} pycodestyle --max-line-length=100 --exclude=.eggs,venv,lib,thirdparty,docs,migrations,settings.py,.cache . @echo "-> Run isort imports ordering validation" - @${ACTIVATE} isort --sl --check-only -l 100 setup.py src tests . + @${ACTIVATE} isort --sl --check-only -l 100 setup.py tests . @echo "-> Run black validation" - @${ACTIVATE} black --check --check -l 100 src tests setup.py + @${ACTIVATE} black --check --check -l 100 tests setup.py clean: @echo "-> Clean the Python env" @@ -49,6 +65,25 @@ test: docs: rm -rf docs/_build/ - @${ACTIVATE} sphinx-build docs/ docs/_build/ + @${ACTIVATE} sphinx-build docs/source docs/_build/ + +postgres: + @echo "-> Configure PostgreSQL database" + @echo "-> Create database user '${POSTGRES_DB}'" + ${SUDO_POSTGRES} createuser --no-createrole --no-superuser --login --inherit --createdb ${POSTGRES_DB} || true + ${SUDO_POSTGRES} psql -c "alter user ${POSTGRES_USER} with encrypted password '${POSTGRES_PASSWORD}';" || true + @echo "-> Drop '${POSTGRES_DB}' database" + ${SUDO_POSTGRES} dropdb ${POSTGRES_DB} || true + @echo "-> Create '${POSTGRES_DB}' database" + ${SUDO_POSTGRES} createdb --encoding=utf-8 --owner=${POSTGRES_USER} ${POSTGRES_DB} + @$(MAKE) migrate + +migrate: + @echo "-> Apply database migrations" + ${MANAGE} migrate + +run: + @echo "-> Starting development server" + ${MANAGE} runserver -.PHONY: conf dev check valid black isort clean test docs +.PHONY: conf dev check valid black isort clean test docs envfile postgres migrate run diff --git a/README.rst b/README.rst index 6cbd839..a69cda7 100644 --- a/README.rst +++ b/README.rst @@ -1,62 +1,24 @@ -A Simple Python Project Skeleton +FederatedCode ================================ -This repo attempts to standardize the structure of the Python-based project's -repositories using modern Python packaging and configuration techniques. -Using this `blog post`_ as inspiration, this repository serves as the base for -all new Python projects and is mergeable in existing repositories as well. - -.. _blog post: https://blog.jaraco.com/a-project-skeleton-for-python-projects/ - +FederatedCode is a decentralized, federated metadata about software applications Usage ===== - -A brand new project -------------------- -.. code-block:: bash - - git init my-new-repo - cd my-new-repo - git pull git@github.com:nexB/skeleton - - # Create the new repo on GitHub, then update your remote - git remote set-url origin git@github.com:nexB/your-new-repo.git - -From here, you can make the appropriate changes to the files for your specific project. - -Update an existing project ---------------------------- -.. code-block:: bash - - cd my-existing-project - git remote add skeleton git@github.com:nexB/skeleton - git fetch skeleton - git merge skeleton/main --allow-unrelated-histories - -This is also the workflow to use when updating the skeleton files in any given repository. - -More usage instructions can be found in ``docs/skeleton-usage.rst``. - - -Release Notes -============= - -- 2023-07-18: - - Add macOS-13 job in azure-pipelines.yml - -- 2022-03-04: - - Synchronize configure and configure.bat scripts for sanity - - Update CI operating system support with latest Azure OS images - - Streamline utility scripts in etc/scripts/ to create, fetch and manage third-party dependencies - There are now fewer scripts. See etc/scripts/README.rst for details - -- 2021-09-03: - - ``configure`` now requires pinned dependencies via the use of ``requirements.txt`` and ``requirements-dev.txt`` - - ``configure`` can now accept multiple options at once - - Add utility scripts from scancode-toolkit/etc/release/ for use in generating project files - - Rename virtual environment directory from ``tmp`` to ``venv`` - - Update README.rst with instructions for generating ``requirements.txt`` and ``requirements-dev.txt``, - as well as collecting dependencies as wheels and generating ABOUT files for them. - -- 2021-05-11: - - Adopt new configure scripts from ScanCode TK that allows correct configuration of which Python version is used. +Getting started +----------------- + +Quick Installation +=================== +On a Debian system, use this:: + sudo apt-get install python3-venv python3-dev postgresql libpq-dev build-essential + git clone https://github.com/nexB/federatedcode.git && cd federatedcode + make dev envfile postgres + make test + source venv/bin/activate + make run + +Acknowledgements +^^^^^^^^^^^^^^^^ +This project was funded through the NGI0 Entrust Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 101069594. + +https://nlnet.nl/project/FederatedSoftwareMetadata/ diff --git a/configure b/configure index 926a894..fa1f9b9 100755 --- a/configure +++ b/configure @@ -28,9 +28,9 @@ CLI_ARGS=$1 ################################ # Requirement arguments passed to pip and used by default or with --dev. -REQUIREMENTS="--editable . --constraint requirements.txt" -DEV_REQUIREMENTS="--editable .[testing] --constraint requirements.txt --constraint requirements-dev.txt" -DOCS_REQUIREMENTS="--editable .[docs] --constraint requirements.txt" +REQUIREMENTS="--editable . -r requirements.txt" +DEV_REQUIREMENTS="--editable .[testing] -r requirements.txt -r requirements-dev.txt" +DOCS_REQUIREMENTS="--editable .[docs] -r requirements.txt" # where we create a virtualenv VIRTUALENV_DIR=venv diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..0a27580 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,40 @@ +version: '3' + +services: + db: + image: postgres:16 + env_file: + - docker.env + volumes: + - db_data:/var/lib/postgresql/data/ + federatedcode: + build: . + command: /bin/sh -c " + apt-get update && apt-get install -y gunicorn && + python manage.py collectstatic --no-input --verbosity 0 --clear && + python manage.py migrate && + gunicorn federatedcode.wsgi:application -u nobody -g nogroup --bind :8000 --timeout 600 --workers 8" + env_file: + - docker.env + expose: + - 8000 + ports: + - "8000:8000" + volumes: + - static:/var/federatedcode/static/ + - /etc/federatedcode/:/etc/federatedcode/ + depends_on: + - db + nginx: + image: nginx + env_file: + - docker.env + volumes: + - ./etc/nginx/conf.d/:/etc/nginx/conf.d + depends_on: + - federatedcode +volumes: + db_data: + static: + federatedcode: + diff --git a/docker.env b/docker.env new file mode 100644 index 0000000..6a1a3b9 --- /dev/null +++ b/docker.env @@ -0,0 +1,15 @@ +FEDERATED_CODE_HOST=127.0.0.1 +FEDERATED_CODE_PORT=8080 +FEDERATED_CODE_DOMAIN=${FEDERATED_CODE_HOST}:${FEDERATED_CODE_PORT} + +POSTGRES_HOST=db +POSTGRES_DB=purl-sync +POSTGRES_USER=purl-sync +POSTGRES_PASSWORD=purl-sync + +FEDERATED_CODE_GIT_PATH=/ +FEDERATED_CODE_CLIENT_ID="" +FEDERATED_CODE_CLIENT_SECRET="" +FEDERATED_CODE_STATIC_ROOT=/var/federatedcode/static/ +STATIC_ROOT=/var/federatedcode/static/ +NGINX_PORT=8080 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 54e5e66..4d575df 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -17,7 +17,7 @@ # -- Project information ----------------------------------------------------- -project = "nexb-skeleton" +project = "federatedcode" copyright = "nexB Inc. and others." author = "AboutCode.org authors and contributors" @@ -30,7 +30,7 @@ extensions = [ "sphinx.ext.intersphinx", "sphinx_reredirects", - 'sphinx_rtd_theme', + "sphinx_rtd_theme", "sphinx_rtd_dark_mode", "sphinx.ext.extlinks", "sphinx_copybutton", @@ -47,7 +47,10 @@ intersphinx_mapping = { "aboutcode": ("https://aboutcode.readthedocs.io/en/latest/", None), - "scancode-workbench": ("https://scancode-workbench.readthedocs.io/en/develop/", None), + "scancode-workbench": ( + "https://scancode-workbench.readthedocs.io/en/develop/", + None, + ), } @@ -108,6 +111,4 @@ # -- Options for LaTeX output ------------------------------------------------- -latex_elements = { - 'classoptions': ',openany,oneside' -} \ No newline at end of file +latex_elements = {"classoptions": ",openany,oneside"} diff --git a/docs/source/contribute/installation.rst b/docs/source/contribute/installation.rst new file mode 100644 index 0000000..b15383d --- /dev/null +++ b/docs/source/contribute/installation.rst @@ -0,0 +1,209 @@ +.. _installation: + +Installation +============ + +.. warning:: + FederatedCode is going through a major structural change and the + installations are likely to not produce enough results. + +Welcome to **FederatedCode** installation guide! This guide describes how to install +FederatedCode on various platforms. +Please read and follow the instructions carefully to ensure your installation is +functional and smooth. + +The **preferred FederatedCode installation** is to :ref:`run_with_docker` as this is +the simplest to setup and get started. +Running FederatedCode with Docker **guarantees the availability of all features** with the +**minimum configuration** required. +This installation **works across all Operating Systems**. + +Alternatively, you can install FederatedCode locally as a development server with some +limitations and caveats. Refer to the :ref:`local_development_installation` section. + +.. _run_with_docker: + +Run with Docker +--------------- + +Get Docker +^^^^^^^^^^ + +The first step is to download and **install Docker on your platform**. +Refer to Docker documentation and choose the best installation +path for your system: `Get Docker `_. + +Build the Image +^^^^^^^^^^^^^^^ + +FederatedCode is distributed with ``Dockerfile`` and ``docker-compose.yml`` files +required for the creation of the Docker image. + +Clone the git `FederatedCode repo `_, +create an environment file, and build the Docker image:: + + git clone https://github.com/nexB/federatedcode.git && cd federatedcode + make envfile + docker-compose build + +.. note:: + + The image will need to be re-built when the FederatedCode app source code is + modified or updated via + ``docker-compose build --no-cache federatedcode`` + +Run the App +^^^^^^^^^^^ + +**Run your image** as a container:: + + docker-compose up + + +At this point, the FederatedCode app should be running at port ``8000`` on your Docker host. +Go to http://localhost:8000/ on a web browser to access the web UI. +Optionally, you can set ``NGINX_PORT`` environment variable in your shell or in the `.env` file +to run on a different port than 8000. + +.. note:: + + To access a dockerized FederatedCode app from a remote location, the ``ALLOWED_HOSTS`` + and ``CSRF_TRUSTED_ORIGINS`` setting need to be provided in your ``docker.env`` file:: + + ALLOWED_HOSTS=.domain.com,127.0.0.1 + CSRF_TRUSTED_ORIGINS=https://*.domain.com,http://127.0.0.1 + + Refer to Django `ALLOWED_HOSTS settings `_ + and `CSRF_TRUSTED_ORIGINS settings `_ + for more details. + +.. warning:: + + Serving FederatedCode on a network could lead to security issues and there + are several steps that may be needed to secure such a deployment. + Currently, this is not recommended. + +.. _local_development_installation: + + +Local development installation +------------------------------ + +Supported Platforms +^^^^^^^^^^^^^^^^^^^ + +**FederatedCode** has been tested and is supported on the following operating systems: + #. **Debian-based** Linux distributions + +.. warning:: + On **Windows** FederatedCode can **only** :ref:`run_with_docker` and is not supported. + +Pre-installation Checklist +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before you install FederatedCode, make sure you have the following prerequisites: + + * **Python: 3.8+** found at https://www.python.org/downloads/ + * **Git**: most recent release available at https://git-scm.com/ + * **PostgreSQL**: release 10 or later found at https://www.postgresql.org/ or + https://postgresapp.com/ on macOS + +.. _system_dependencies: + +System Dependencies +^^^^^^^^^^^^^^^^^^^ + +In addition to the above pre-installation checklist, there might be some OS-specific +system packages that need to be installed before installing FederatedCode. + +On **Debian-based distros**, several **system packages are required** by FederatedCode. +Make sure those are installed:: + + sudo apt-get install python3-venv python3-dev postgresql libpq-dev build-essential + + +Clone and Configure +^^^^^^^^^^^^^^^^^^^ + +Clone the `FederatedCode Git repository `_:: + + git clone https://github.com/nexB/federatedcode.git && cd federatedcode + +Install the required dependencies:: + + make dev + +.. note:: + + You can specify the Python version during the ``make dev`` step using the following + command:: + + make dev PYTHON_EXE=python3.8.10 + + When ``PYTHON_EXE`` is not specified, by default, the ``python3`` executable is + used. + +Create an environment file:: + + make envfile + + +Database +^^^^^^^^ + +**PostgreSQL** is the preferred database backend and should always be used on +production servers. + +* Create the PostgreSQL user, database, and table with:: + + make postgres + +Tests +^^^^^ + +You can validate your federatedcode installation by running the tests suite:: + + make test + +Import a Service like ( VCIO , .. ) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Create a Superuser:: + + python manage.py createsuperuser + +Create a Service: + +using django-admin panel create user as service admin then create a Service 'vcio' +login using service admin credential then create a new git repository ex: https://github.com/nexB/vulnerablecode-data + +Create a Sync request and Import git repository data: +click on the sync button under the git repository url then run: ``python manage.py tasks sync`` + + +Web Application +^^^^^^^^^^^^^^^ + +A web application is available to create and manage your projects from a browser; +you can start the local webserver and access the app with:: + + make run + +Then open your web browser and visit: http://127.0.0.1:8000/ to access the web +application. + +.. warning:: + This setup is **not suitable for deployments** and **only supported for local + development**. + + +Upgrading +^^^^^^^^^ + +If you already have the FederatedCode repo cloned, you can upgrade to the latest version +with:: + + cd federatedcode + git pull + make dev + make migrate + diff --git a/docs/source/contribute/vocabulary.rst b/docs/source/contribute/vocabulary.rst new file mode 100644 index 0000000..6094691 --- /dev/null +++ b/docs/source/contribute/vocabulary.rst @@ -0,0 +1,257 @@ +.. _vocabulary: + +FederatedCode Vocabulary +========================= +FederatedCode Vocabulary’s intended to be an extension of +`Activity Vocabulary `__. + +Actors +******* + +Package +------- + .. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Package", + "name": "vcio", + "followers": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/followers/", + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "inbox": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/inbox", + "outbox": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/outbox", + "publicKey": { + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "owner": "https://127.0.0.1:8000/api/v0/users/@ziad", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC " "KEY-----", + } + } + +Person +------- +.. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Person", + "summary": "Hello This is my profile", + "following": "https://127.0.0.1:8000/api/v0/users/@ziad/following/", + "id": "https://127.0.0.1:8000/api/v0/users/@ziad", + "image": "https://127.0.0.1:8000/media/favicon-16x16.png", + "inbox": "https://127.0.0.1:8000/api/v0/users/@ziad/inbox", + "name": "ziad", + "outbox": "https://127.0.0.1:8000/api/v0/users/@ziad/outbox", + "publicKey": { + "id": "https://127.0.0.1:8000/api/v0/users/@ziad", + "owner": "https://127.0.0.1:8000/api/v0/users/@ziad", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC " "KEY-----", + } + } + +Service +------- +.. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Service", + "name": "vcio" + } + +Activity +******** + +Follow +------- + .. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Follow", + "actor": "https://127.0.0.1:8000/api/v0/users/@ziad", + "object": { + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "type": "Purl" + }, + } + +Create +------- + .. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Create", + "actor": "https://127.0.0.1:8000/api/v0/users/@vcio", + "object": { + "type": "Repository", + "name": "vulnerablecode", + "url": "https://github.com/nexB/vulnerablecode-data", + }, + } + +Update +------- + .. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Update", + "actor": "https://127.0.0.1:8000/api/v0/users/@ziad", + "object": { + "id": "https://127.0.0.1:8000/notes/3701d4b6-a7cf-41ee-9144-35f9d70afe0b", + "type": "Note", + "content": "Hello World!", + }, + } + +Delete +------- + .. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Delete", + "actor": "https://127.0.0.1:8000/api/v0/users/@ziad", + "object": { + "type": "Note", + "id": "https://127.0.0.1:8000/notes/3701d4b6-a7cf-41ee-9144-35f9d70afe0b", + }, + } + + +UnFollow +-------- + .. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "UnFollow", + "actor": "https://127.0.0.1:8000/api/v0/users/@ziad", + "object": { + "type": "Purl", + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + }, + } + +Sync +----- + .. code-block:: JSON + + { + "@context": ["https://www.w3.org/ns/activitystreams", "....."], + "type": "Sync", + "actor": "https://127.0.0.1:8000/users/@vcio", + "object": { + "type": "Repository", + "id": "https://127.0.0.1:8000/repository/3701d4b6-a7cf-41ee-9144-35f9d70afe0b/", + }, + } + +Objects +******** + +Note +----- + + .. code-block:: JSON + + { + "type": "Note", + "id": "https://127.0.0.1:8000/notes/3701d4b6-a7cf-41ee-9144-35f9d70afe0b", + "author": "pkg:maven/org.apache.logging@127.0.0.1:8000", + "content": "purl: pkg:maven/org.apache.logging@2.23-r0?arch=aarch64&distroversion=edge&reponame=community + affected_by_vulnerabilities: [] + fixing_vulnerabilities: []", + "mediaType": "application/yaml" + } + +OR Note +-------- + + .. code-block:: JSON + + { + "type": "Note", + "id": "https://127.0.0.1:8000/notes/3701d4b6-a7cf-41ee-9144-35f9d70afe0b", + "author": "ziad@vcio", + "content": "I think this review ", + "mediaType": "text/plain" + "reply_to": "https://127.0.0.1:8000/notes/de5a3ab3-9ec7-4943-8061-cbe4b8f01942", + } + + +Review +------- + .. code-block:: JSON + + { + "id": "https://127.0.0.1:8000/reviews/3701d4b6-a7cf-41ee-9144-35f9d70afe0b/", + "type": "Review", + "author": "https://127.0.0.1:8000/api/v0/users/@ziad", + "headline": "Missing data at ( VCIO-xx-xx-xx )", + "filepath": "/apache/httpd/VCID-1a68-fd5t-aaam.yml", + "repository": "https://127.0.0.1:8000/repository/3701d4b6-a7cf-41ee-9144-35f9d70afe0b/", + "content": "diff text", + "commit": "104ccd6a7a41329b2953c96e52792a3d6a9ad8e5", + "comments": { + "type": "OrderedCollection", + "totalItems": 1, + "orderedItems": [ + { "type": "Note", + "id": "https://127.0.0.1:8000/notes/3701d4b6-a7cf-41ee-9144-35f9d70afe0b", + "author": "https://127.0.0.1:8000/api/v0/users/@ziad", + "content": "The affected_by_vulnerabilities should be [ ... ] ", + } + ], + }, + "published": "2015-02-10T15:04:55Z", + "updated": "2015-02-10T15:04:55Z", + } + +Repository +------------ + .. code-block:: JSON + + { + "id": "https://127.0.0.1:8000/repository/dfc1f9bf-3f23-484b-9187-4c9bc89d7cbb/", + "type": "Repository", + "url": "https://github.com/nexB/fake-repo" + } + +Vulnerability +--------------- + .. code-block:: JSON + + { + "id": "https://127.0.0.1:8000/vulnerability/VCID-1155-4sem-aaaq/", + "type": "Vulnerability", + "repository": "https://127.0.0.1:8000/repository/dfc1f9bf-3f23-484b-9187-4c9bc89d7cbb/", + } + + +Like +------ + .. code-block:: JSON + + { + "type": "Like", + "actor": "ziad@vcio", + "object": { + "type": "Note", + "content": "A simple note" + } + } + +Dislike +-------- + .. code-block:: JSON + + { + "type": "Dislike", + "actor": "ziad@vcio", + "object": { + "type": "Note", + "content": "A simple note" + } + } diff --git a/docs/source/index.rst b/docs/source/index.rst index eb63717..062ea74 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,13 +1,16 @@ -Welcome to nexb-skeleton's documentation! -========================================= +Welcome to Federated Code's documentation! +=========================================== .. toctree:: :maxdepth: 2 - :caption: Contents: + :caption: Getting Started: + contribute/installation + contribute/vocabulary skeleton-usage contribute/contrib_doc + Indices and tables ================== diff --git a/etc/nginx/conf.d/default.conf b/etc/nginx/conf.d/default.conf new file mode 100644 index 0000000..eb94757 --- /dev/null +++ b/etc/nginx/conf.d/default.conf @@ -0,0 +1,20 @@ +upstream gunicorn_app { + server federatedcode:8000; +} + +server { + listen 80; + + location / { + proxy_pass http://gunicorn_app; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + client_max_body_size 10G; + proxy_read_timeout 600s; + } + + location /static/ { + alias /var/federatedcode/static/; + } +} diff --git a/etc/scripts/check_thirdparty.py b/etc/scripts/check_thirdparty.py index b052f25..999d112 100644 --- a/etc/scripts/check_thirdparty.py +++ b/etc/scripts/check_thirdparty.py @@ -9,7 +9,6 @@ # See https://aboutcode.org for more information about nexB OSS projects. # import click - import utils_thirdparty diff --git a/etc/scripts/fetch_thirdparty.py b/etc/scripts/fetch_thirdparty.py index eedf05c..a84b6c4 100644 --- a/etc/scripts/fetch_thirdparty.py +++ b/etc/scripts/fetch_thirdparty.py @@ -15,9 +15,8 @@ from collections import defaultdict import click - -import utils_thirdparty import utils_requirements +import utils_thirdparty TRACE = False TRACE_DEEP = False @@ -120,7 +119,7 @@ show_default=False, multiple=True, help="Package name(s) that come only in sdist format (no wheels). " - "The command will not fail and exit if no wheel exists for these names", + "The command will not fail and exit if no wheel exists for these names", ) @click.option( "--wheel-only", @@ -131,7 +130,7 @@ show_default=False, multiple=True, help="Package name(s) that come only in wheel format (no sdist). " - "The command will not fail and exit if no sdist exists for these names", + "The command will not fail and exit if no sdist exists for these names", ) @click.option( "--no-dist", @@ -142,7 +141,7 @@ show_default=False, multiple=True, help="Package name(s) that do not come either in wheel or sdist format. " - "The command will not fail and exit if no distribution exists for these names", + "The command will not fail and exit if no distribution exists for these names", ) @click.help_option("-h", "--help") def fetch_thirdparty( @@ -248,7 +247,6 @@ def fetch_thirdparty( print(f"Processing: {name} @ {version}") if wheels: for environment in environments: - if TRACE: print(f" ==> Fetching wheel for envt: {environment}") @@ -264,9 +262,7 @@ def fetch_thirdparty( if TRACE: print(f" NOT FOUND") - if (sdists or - (f"{name}=={version}" in wheels_or_sdist_not_found and name in sdist_only) - ): + if sdists or (f"{name}=={version}" in wheels_or_sdist_not_found and name in sdist_only): if TRACE: print(f" ==> Fetching sdist: {name}=={version}") diff --git a/etc/scripts/gen_pypi_simple.py b/etc/scripts/gen_pypi_simple.py index 214d90d..1790dee 100644 --- a/etc/scripts/gen_pypi_simple.py +++ b/etc/scripts/gen_pypi_simple.py @@ -69,7 +69,6 @@ def get_package_name_from_filename(filename): raise InvalidDistributionFilename(filename) elif filename.endswith(wheel_ext): - wheel_info = get_wheel_from_filename(filename) if not wheel_info: @@ -204,7 +203,6 @@ def build_pypi_index(directory, base_url="https://thirdparty.aboutcode.org/pypi" ] for pkg_file in directory.iterdir(): - pkg_filename = pkg_file.name if ( diff --git a/etc/scripts/test_utils_pip_compatibility_tags.py b/etc/scripts/test_utils_pip_compatibility_tags.py index 98187c5..15cff45 100644 --- a/etc/scripts/test_utils_pip_compatibility_tags.py +++ b/etc/scripts/test_utils_pip_compatibility_tags.py @@ -25,11 +25,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -from unittest.mock import patch import sysconfig +from unittest.mock import patch import pytest - import utils_pip_compatibility_tags diff --git a/etc/scripts/test_utils_pypi_supported_tags.py b/etc/scripts/test_utils_pypi_supported_tags.py index d291572..576321e 100644 --- a/etc/scripts/test_utils_pypi_supported_tags.py +++ b/etc/scripts/test_utils_pypi_supported_tags.py @@ -11,7 +11,6 @@ # limitations under the License. import pytest - from utils_pypi_supported_tags import validate_platforms_for_pypi """ diff --git a/etc/scripts/utils_dejacode.py b/etc/scripts/utils_dejacode.py index c42e6c9..af94aab 100644 --- a/etc/scripts/utils_dejacode.py +++ b/etc/scripts/utils_dejacode.py @@ -14,7 +14,6 @@ import requests import saneyaml - from packvers import version as packaging_version """ diff --git a/etc/scripts/utils_pip_compatibility_tags.py b/etc/scripts/utils_pip_compatibility_tags.py index af42a0c..de0ac95 100644 --- a/etc/scripts/utils_pip_compatibility_tags.py +++ b/etc/scripts/utils_pip_compatibility_tags.py @@ -27,14 +27,12 @@ import re -from packvers.tags import ( - compatible_tags, - cpython_tags, - generic_tags, - interpreter_name, - interpreter_version, - mac_platforms, -) +from packvers.tags import compatible_tags +from packvers.tags import cpython_tags +from packvers.tags import generic_tags +from packvers.tags import interpreter_name +from packvers.tags import interpreter_version +from packvers.tags import mac_platforms _osx_arch_pat = re.compile(r"(.+)_(\d+)_(\d+)_(.+)") diff --git a/etc/scripts/utils_thirdparty.py b/etc/scripts/utils_thirdparty.py index addf8e5..9c9ff94 100644 --- a/etc/scripts/utils_thirdparty.py +++ b/etc/scripts/utils_thirdparty.py @@ -25,14 +25,13 @@ import packageurl import requests import saneyaml +import utils_pip_compatibility_tags from commoncode import fileutils from commoncode.hash import multi_checksums from commoncode.text import python_safe_name from packvers import tags as packaging_tags from packvers import version as packaging_version -import utils_pip_compatibility_tags - """ Utilities to manage Python thirparty libraries source, binaries and metadata in local directories and remote repositories. @@ -355,7 +354,6 @@ def sorted(cls, namevers): @attr.attributes class Distribution(NameVer): - # field names that can be updated from another Distribution or mapping updatable_fields = [ "license_expression", @@ -1091,7 +1089,6 @@ def get_sdist_name_ver_ext(filename): @attr.attributes class Sdist(Distribution): - extension = attr.ib( repr=False, type=str, @@ -2137,7 +2134,6 @@ def call(args, verbose=TRACE): with subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8" ) as process: - stdouts = [] while True: line = process.stdout.readline() diff --git a/fedcode/__init__.py b/fedcode/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fedcode/activitypub.py b/fedcode/activitypub.py new file mode 100644 index 0000000..31f0b74 --- /dev/null +++ b/fedcode/activitypub.py @@ -0,0 +1,609 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import json +import logging +from dataclasses import asdict +from dataclasses import dataclass +from dataclasses import field +from typing import Literal +from typing import Optional +from urllib.parse import urlparse + +from django.contrib.auth.models import User +from django.http import HttpResponseBadRequest +from django.http import JsonResponse +from django.urls import resolve + +from federatedcode.settings import FEDERATED_CODE_DOMAIN +from federatedcode.settings import FEDERATED_CODE_GIT_PATH + +from .models import Follow, FederateRequest +from .models import Note +from .models import Person +from .models import Package +from .models import RemoteActor +from .models import Repository +from .models import Review +from .models import Service +from .models import Vulnerability +from .utils import fetch_actor +from .utils import full_resolve +from .utils import full_reverse +from .utils import webfinger_actor + +CONTENT_TYPE = "application/activity+json" +ACTOR_TYPES = ["Person", "Package"] + +ACTOR_PAGES = {"purl-profile": Package, "user-profile": Person} + +ACTIVITY_TYPES = ["Follow", "UnFollow", "Create", "Update", "Delete", "Sync"] + +OBJECT_TYPES = { + "Note": Note, + "Review": Review, + "Repository": Repository, + "Vulnerability": Vulnerability, +} + +AP_VALID_HEADERS = [ + 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', + "application/activity+json", +] + +AP_CONTEXT = { + "@context": ["https://www.w3.org/ns/activitystreams", "https://www.aboutcode.org/ns/federatedcode"], +} + +AP_TARGET = {"cc": "https://www.w3.org/ns/activitystreams#Public"} + +OBJ_PAGE = { + "Note": "note-page", + "Review": "review-page", + "Repository": "repository-page", + "Vulnerability": "vulnerability-page", +} + +URL_MAPPER = { + "user-ap-profile": "username", + "purl-ap-profile": "purl_string", + "review-page": "uuid", + "repository-page": "uuid", + "note-page": "uuid", + "vulnerability-page": "str", +} + +logger = logging.getLogger(__name__) + + +def check_and_r_ap_context(request): + """ + check activitypub context request and return request without @context + """ + if request.get("@context") == AP_CONTEXT["@context"]: + request.pop("@context") + return request + else: + return None + + +def add_ap_target(response): + """ + Add target activitypub response + """ + if response is not dict: + raise KeyError("Invalid response") + + if not response.get("cc"): + response.append(**AP_TARGET) + + return response + + +def has_valid_header(view): + """ + check if the request header in the AP_VALID_HEADERS if yes return view else return HttpResponseForbidden + """ + + def wrapper(request, *args, **kwargs): + content_type = request.headers.get("Content-Type") + if content_type in AP_VALID_HEADERS: + return view(request, *args, **kwargs) + else: + return + + return wrapper + + +@dataclass +class Activity: + type: Literal["Follow", "UnFollow", "Create", "Update", "Delete", "Sync"] + actor: Optional[str | dict] + object: Optional[str | dict] + to: list = field(default_factory=list) + id: str = None + + def handler(self): + ap_actor = ApActor(**self.actor) if isinstance(self.actor, dict) else ApActor(id=self.actor) + if self.type in ["Follow", "UnFollow"]: + ap_object = ( + ApActor(**self.object) if isinstance(self.object, dict) else ApActor(id=self.object) + ) + else: + ap_object = ( + ApObject(**self.object) if isinstance(self.object, dict) else ApObject(id=self.object) + ) + return ACTIVITY_MAPPER[self.type](actor=ap_actor, object=ap_object, to=self.to).save() + + @classmethod + def federate(cls, targets, body, key_id): + """ + Send the signed request body and key_id to the targets list of domains + """ + for target in targets: + target_domain = urlparse(target).netloc + if target_domain != FEDERATED_CODE_DOMAIN: # TODO Add a server whitelist if necessary + try: + FederateRequest.objects.create(target=target, body=body, key_id=key_id) + except Exception as e: + logger.error(f"{e}") + + +@dataclass +class ApActor: + type: Literal["Person", "Package"] = None + id: str = None + name: Optional[str] = None + purl: Optional[str] = None + summary: Optional[str] = None + inbox: str = None + outbox: str = None + following: Optional[str] = None + followers: Optional[str] = None + image: Optional[str] = None + + def get_by_type(self): + if self.type in ACTOR_TYPES: + if self.type == ACTOR_TYPES[0]: + return Person.objects.get_or_none(user__username=self.name).to_ap() + + elif self.type == ACTOR_TYPES[1]: + return Package.objects.get_or_none(purl=self.name).to_ap() + + def get(self): + obj_id, page_name = full_resolve(self.id) + if page_name == "purl-ap-profile": + try: + purl = Package.objects.get(purl=obj_id["purl_string"]) + except Package.DoesNotExist: + purl = None + return purl + + elif page_name == "user-ap-profile": + try: + user = User.objects.get(username=obj_id["username"]) + if hasattr(user, "person"): + return user.person + elif hasattr(user, "service"): + return user.service + except User.DoesNotExist: + user = None + return None + + +@dataclass +class ApObject: + type: Literal["Note", "Review", "Repository", "Vulnerability"] = None + id: str = None + content: str = None + reply_to: str = None + repository: str = None + filename: str = None + headline: str = None + name: str = None + url: str = None + vulnerability: str = None + commit: str = None + filepath: str = None + + def get(self): + if self.id: + obj_id, page_name = full_resolve(self.id) + identifier = URL_MAPPER[page_name] + return OBJECT_TYPES[self.type].objects.get(id=obj_id[identifier]) + raise ValueError("Invalid object id") + + +@dataclass +class FollowActivity: + """ + https://www.w3.org/ns/activitystreams#Follow + """ + type = "Follow" + actor: ApActor + object: ApActor + to: list = field(default_factory=list) + + def save(self): + """ + Save the follow relationship between the actor and the package + + steps: + + 1. check if actor url ( id ) domain equal to server domain + if not, fetch the remote actor and create a new actor remote + + 2. check if package url ( id ) equal to server domain + if not, fetch the remote actor and create a new actor remote + + 3.create a Follow relationship and return a success message + """ + person = self.actor.get() + package = self.object.get() + + if not (package or person): + return self.failed_ap_rs() + + if not person: + # remote actor + person_webfinger_url = check_remote_actor(self.actor.id) + if not person_webfinger_url: # INVALID DOMAIN + return self.failed_ap_rs() + + person_details = fetch_actor(person_webfinger_url) + + if not isinstance(person_details, dict): + return self.failed_ap_rs() + + if not (person_details.get("name") and person_details.get("id")): + return self.failed_ap_rs() + + remote_actor, created = RemoteActor.objects.get_or_create( + username=person_details["name"], url=person_details["id"] + ) + person, created = Person.objects.get_or_create(remote_actor=remote_actor) + + if not package: + # remote package + package_webfinger_url = check_remote_actor(self.object.id) + + if not package_webfinger_url: # INVALID DOMAIN + return self.failed_ap_rs() + package_details = fetch_actor(package_webfinger_url) + + if not isinstance(package_details, dict): + return self.failed_ap_rs() + + if not (package_details.get("name") and package_details.get("id")): + return self.failed_ap_rs() + + remote_actor, created = RemoteActor.objects.get_or_create( + username=package_details["name"], url=package_details["id"] + ) + package, created = Package.objects.get_or_create( + remote_actor=remote_actor, purl=package_details["purl"] + ) + + if person and package: + Follow.objects.get_or_create(person=person, package=package) + Activity.federate(targets=self.to, body=self.to_ap(), key_id=person.key_id) + return self.succeeded_ap_rs() + return self.failed_ap_rs() + + def succeeded_ap_rs(self): + """Response for successfully deleting the object""" + return JsonResponse({}, status=201) + + def failed_ap_rs(self): + """Response for failure deleting the object""" + return JsonResponse({}, status=405) + + def to_ap(self): + """Follow activity in activitypub format""" + return { + **AP_CONTEXT, + "type": self.type, + "actor": asdict(self.actor), + "object": asdict(self.object), + "to": self.to, + **AP_TARGET, + } + + +@dataclass +class CreateActivity: + """ + https://www.w3.org/TR/activitypub/#create-activity-outbox + """ + type = "Create" + actor: ApActor + object: ApObject + to: list = field(default_factory=list) + + def save(self): + new_obj, created = None, None + actor = self.actor.get() + if not actor: + return self.failed_ap_rs() + + if isinstance(actor, Person): + if self.object.type == "Note": + reply_to = None + if self.object.reply_to: + note_id = full_resolve(self.object.reply_to) + reply_to = Note.objects.get_or_none(id=note_id) + + new_obj, created = Note.objects.get_or_create( + acct=actor.acct, + content=self.object.content, + reply_to=reply_to, + ) + elif self.object.type == "Review" and self.object.repository: + obj_id, page_name = full_resolve(self.object.repository) + repo = Repository.objects.get(id=obj_id["repository_id"]) + + new_obj, created = Review.objects.get_or_create( + headline=self.object.headline, + author=actor, + filepath=self.object.filepath, + repository=repo, + data=self.object.content, + commit=self.object.commit, + status=0, # OPEN + ) + Activity.federate(targets=self.to, body=self.to_ap(), key_id=actor.key_id) + elif isinstance(actor, Package): + if self.object.type == "Note": + reply_to = None + if self.object.reply_to: + note_id = self.object.reply_to + reply_to = Note.objects.get_or_none(id=note_id) + + new_obj, created = Note.objects.get_or_create( + acct=actor.acct, + content=self.object.content, + reply_to=reply_to, + ) + Activity.federate(targets=self.to, body=self.to_ap(), key_id=actor.key_id) + elif isinstance(actor, Service): + if self.object.type == "Repository": + new_obj, created = Repository.objects.get_or_create( + url=self.object.url, + path=FEDERATED_CODE_GIT_PATH, + admin=actor, + ) + + return self.succeeded_ap_rs(new_obj) if created else self.failed_ap_rs() + + def succeeded_ap_rs(self, new_obj): + """Response for successfully deleting the object""" + return JsonResponse( + {"Location": full_reverse(OBJ_PAGE[self.object.type], new_obj.id)}, + status=201, + ) + + def failed_ap_rs(self): + """Response for failure deleting the object""" + return HttpResponseBadRequest("Invalid Create Activity request") + + def to_ap(self): + """Request for creating object in activitypub format""" + return { + **AP_CONTEXT, + "type": self.type, + "actor": self.actor if isinstance(self.actor, dict) else asdict(self.actor), + "object": self.object if isinstance(self.actor, dict) else asdict(self.object), + "to": self.to, + **AP_TARGET, + } + + +@dataclass +class UpdateActivity: + """ + https://www.w3.org/TR/activitystreams-vocabulary/#dfn-update + """ + type = "Update" + actor: ApActor + object: ApObject + to: list = field(default_factory=list) + + def save(self): + updated_obj = None + actor = self.actor.get() + old_obj = self.object.get() + if not actor: + return self.failed_ap_rs() + + updated_param = { + "Note": {"content": self.object.content}, + "Review": {"headline": self.object.headline, "data": self.object.content}, + "Repository": {"url": self.object.url}, + } + + if ( + (isinstance(actor, Person) and self.object.type in ["Note", "Review"]) + or (isinstance(actor, Service) and self.object.type == "Repository") + or (isinstance(actor, Package) and self.object.type == "Note") + ): + for key, value in updated_param[self.object.type].items(): + if value: + setattr(old_obj, key, value) + old_obj.save() + + Activity.federate(targets=self.to, body=self.to_ap(), key_id=actor.key_id) + return self.succeeded_ap_rs(old_obj.to_ap) + + def succeeded_ap_rs(self, update_obj): + """Response for successfully deleting the object""" + return JsonResponse(update_obj, status=200) + + def failed_ap_rs(self): + """Response for failure deleting the object""" + return HttpResponseBadRequest("Method Not Allowed", status=405) + + def to_ap(self): + """Request for updating object in activitypub format""" + return { + **AP_CONTEXT, + "type": self.type, + "actor": asdict(self.actor), + "object": asdict(self.object), + "to": self.object, + **AP_TARGET, + } + + +@dataclass +class DeleteActivity: + """ + https://www.w3.org/ns/activitystreams#Delete + """ + actor: ApActor + object: ApObject + type = "Delete" + to: list = field(default_factory=list) + + def save(self): + actor = self.actor.get() + if not actor: + return self.failed_ap_rs() + + if ( + (type(actor) is Person and self.object.type in ["Note", "Review"]) + or (type(actor) is Package and self.object.type in ["Note"]) + or (type(actor) is Service and self.object.type == ["Repository", "Package"]) + ): + instance = self.object.get() + instance.delete() + Activity.federate(targets=self.to, body=self.to_ap(), key_id=actor.key_id) + return self.succeeded_ap_rs() + else: + return self.failed_ap_rs() + + def ap_rq(self): + """Request for deleting object in activitypub format""" + return {**AP_CONTEXT, "type": self.type, "actor": self.actor, "to": self.object} + + def succeeded_ap_rs(self): + """Response for successfully deleting the object""" + return JsonResponse({"message": "The object has been deleted successfully"}, status=200) + + def failed_ap_rs(self): + """Response for failure deleting the object""" + return JsonResponse("Invalid object", status=404) + + def to_ap(self): + return { + **AP_CONTEXT, + "type": self.type, + "actor": asdict(self.actor), + "object": asdict(self.object), + "to": self.object, + **AP_TARGET, + } + + +def create_activity_obj(data): + """Convert json object to activity object""" + payload = json.loads(data) + payload_without_context = check_and_r_ap_context(payload) + return Activity(**payload_without_context) + + +@dataclass +class UnFollowActivity: + """""" + type = "UnFollow" + actor: ApActor + object: ApActor + to: list = field(default_factory=list) + + def save(self): + actor = self.actor.get() + if not type(actor) is Person: + return self.failed_ap_rs() + else: + obj_id, page_name = full_resolve(self.object.id) + package = Package.objects.get(purl=obj_id["purl_string"]) + follow_obj = Follow.objects.get(person_id=actor.id, package=package) + follow_obj.delete() + return self.succeeded_ap_rs() + + def succeeded_ap_rs(self): + """Response for successfully deleting the object""" + return JsonResponse({"Location": ""}, status=201) + + def failed_ap_rs(self): + """Response for failure deleting the object""" + return JsonResponse({}, status=405) + + def to_ap(self): + """Follow activity in activitypub format""" + return { + **AP_CONTEXT, + "type": self.type, + "actor": asdict(self.actor), + "object": asdict(self.object), + "to": self.object, + **AP_TARGET, + } + + +@dataclass +class SyncActivity: + """ + The Sync activity is a custom activity where a Service user + can send a request to run the Importer and receive + all the followed Package data + """ + type = "Sync" + actor: ApActor + object: ApObject + to: list = field(default_factory=list) + + def save(self): + actor = self.actor.get() + if not actor: + return self.failed_ap_rs() + repo = self.object.get().git_repo_obj + repo.remotes.origin.pull() + return self.succeeded_ap_rs() + + def succeeded_ap_rs(self): + """Response for successfully deleting the object""" + return JsonResponse({}, status=201) + + def failed_ap_rs(self): + """Response for failure deleting the object""" + return JsonResponse({}, status=405) + + +ACTIVITY_MAPPER = { + "Create": CreateActivity, + "Update": UpdateActivity, + "Delete": DeleteActivity, + "Follow": FollowActivity, + "UnFollow": UnFollowActivity, + "Sync": SyncActivity, +} + + +def check_remote_actor(key_id): + """ + check if url is remote actor + if valid remote actor return actor webfinger + """ + parser = urlparse(key_id) + if parser.netloc == FEDERATED_CODE_DOMAIN: # INVALID DOMAIN ( Server Domain ) + return + + resolver = resolve(parser.path) + obj_id, page_name = resolver.kwargs, resolver.url_name + identity = URL_MAPPER[page_name] + return webfinger_actor(parser.netloc, resolver.kwargs[identity]) diff --git a/fedcode/admin.py b/fedcode/admin.py new file mode 100644 index 0000000..e2421a4 --- /dev/null +++ b/fedcode/admin.py @@ -0,0 +1,37 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +from django.contrib import admin + +from .models import Follow +from .models import Note +from .models import Person +from .models import Package +from .models import RemoteActor +from .models import Repository +from .models import Reputation +from .models import Review +from .models import Service +from .models import Vulnerability +from .models import SyncRequest +from .models import FederateRequest + +admin.site.register(Person) +admin.site.register(Service) + +admin.site.register(Repository) +admin.site.register(Vulnerability) +admin.site.register(Package) +admin.site.register(Note) +admin.site.register(Follow) +admin.site.register(Review) +admin.site.register(Reputation) + +admin.site.register(RemoteActor) +admin.site.register(SyncRequest) +admin.site.register(FederateRequest) diff --git a/fedcode/apps.py b/fedcode/apps.py new file mode 100644 index 0000000..df93727 --- /dev/null +++ b/fedcode/apps.py @@ -0,0 +1,14 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +from django.apps import AppConfig + + +class FedcodeConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "fedcode" diff --git a/fedcode/forms.py b/fedcode/forms.py new file mode 100644 index 0000000..82b3a23 --- /dev/null +++ b/fedcode/forms.py @@ -0,0 +1,144 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +from django import forms +from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.models import User + +from .models import Note +from .models import Repository +from .models import Review + + +class CreateGitRepoForm(forms.ModelForm): + class Meta: + model = Repository + fields = ["url"] + help_texts = { + 'url': None, + } + + def __init__(self, *args, **kwargs): + super(CreateGitRepoForm, self).__init__(*args, **kwargs) + self.fields["url"].widget.attrs.update({"class": "input mb-5", + "placeholder": "https://github.com/nexB/vulnerablecode-data"}) + + +class CreateNoteForm(forms.ModelForm): + class Meta: + model = Note + fields = ["content"] + + def __init__(self, *args, **kwargs): + super(CreateNoteForm, self).__init__(*args, **kwargs) + self.fields["content"].widget.attrs.update( + {"class": "textarea", "placeholder": "Add a note...", "rows": 5} + ) + self.fields["content"].label = "" + + +class ReviewStatusForm(forms.ModelForm): + class Meta: + model = Review + fields = ["status"] + help_texts = { + 'status': None, + } + + def __init__(self, *args, **kwargs): + super(ReviewStatusForm, self).__init__(*args, **kwargs) + self.fields["status"].widget.attrs.update({"class": "input mb-5"}) + + +class PersonSignUpForm(UserCreationForm): + email = forms.EmailField(max_length=254) + + class Meta: + model = User + fields = ( + "username", + "email", + "password1", + "password2", + ) + + +class CreateReviewForm(forms.Form): + headline = forms.CharField( + widget=forms.TextInput( + attrs={ + "class": "input is-medium title has-text-centered", + "placeholder": "Review Title", + } + ) + ) + data = forms.CharField(widget=forms.Textarea(attrs={"class": "textarea", "rows": 16})) + filename = forms.CharField(widget=forms.HiddenInput()) + + +class FetchForm(forms.Form): + file_path = forms.CharField( + widget=forms.TextInput( + attrs={ + "class": "input", + "placeholder": "alpine/dia/VCID-xxx-xxx-xxx.yaml", + } + ) + ) + + +class SubscribePackageForm(forms.Form): + acct = forms.CharField( + label="Subscribe with a remote account:", + widget=forms.TextInput( + attrs={"placeholder": "ziadhany@vulnerablecode.io", "class": "input"} + ), + ) + + +class SearchPackageForm(forms.Form): + search = forms.CharField( + required=True, + label=False, + widget=forms.TextInput( + attrs={ + "placeholder": "Please entre a valid purl ex: pkg:maven/org.apache.commons/io@1.3.4", + "class": "input is-rounded", + "style": "width: 90%;", + }, + ), + ) + + +class SearchReviewForm(forms.Form): + search = forms.CharField( + required=True, + label=False, + widget=forms.TextInput( + attrs={ + "placeholder": "Please Entre a valid Review Name", + "class": "input is-rounded", + "style": "width: 90%;", + }, + ), + ) + + +class SearchRepositoryForm(forms.Form): + search = forms.CharField( + required=True, + label=False, + widget=forms.TextInput( + attrs={ + "placeholder": "Please Entre a Repository URL ex: https://github.com/nexB/vulnerablecode-data", + "class": "input is-rounded", + "style": "width: 90%;", + }, + ), + ) diff --git a/fedcode/importer.py b/fedcode/importer.py new file mode 100644 index 0000000..058805f --- /dev/null +++ b/fedcode/importer.py @@ -0,0 +1,179 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import logging +import os.path +from dataclasses import dataclass +from itertools import zip_longest + +import saneyaml + +from fedcode.activitypub import Activity +from fedcode.activitypub import CreateActivity +from fedcode.activitypub import DeleteActivity +from fedcode.activitypub import UpdateActivity +from fedcode.models import Note +from fedcode.models import Package +from fedcode.models import Repository +from fedcode.models import Service +from fedcode.models import Vulnerability + +logger = logging.getLogger(__name__) + + +@dataclass +class Importer: + repo_obj: Repository + default_service: Service + + def run(self): + repo = self.repo_obj.git_repo_obj + latest_commit_hash = repo.heads.master.commit.hexsha + latest_commit = repo.commit(latest_commit_hash) + if self.repo_obj.last_imported_commit: + last_imported_commit = repo.commit(self.repo_obj.last_imported_commit) + diffs = last_imported_commit.diff(latest_commit) + else: + last_imported_commit = None + # Diff between empty trees and last_imported_commit + diffs = latest_commit.diff("4b825dc642cb6eb9a060e54bf8d69288fbee4904", R=True) + + if repo.heads.master.commit.hexsha == self.repo_obj.last_imported_commit: + logger.error("Nothing to import!") + return + + for diff in diffs: + if not diff.a_path.endswith(".yml"): + continue + + if diff.a_path.startswith("."): + continue + + yaml_data_a_blob = ( + saneyaml.load(diff.a_blob.data_stream.read()) if diff.a_blob else None + ) + yaml_data_b_blob = ( + saneyaml.load(diff.b_blob.data_stream.read()) if diff.b_blob else None + ) + + if os.path.split(diff.a_path)[1].startswith("VCID") or os.path.split(diff.b_path)[ + 1 + ].startswith("VCID"): + vul_handler(diff.change_type, self.repo_obj, yaml_data_a_blob, yaml_data_b_blob, + diff.a_path, diff.b_path) + continue + + pkg_handler( + diff.change_type, + self.default_service, + yaml_data_a_blob, + yaml_data_b_blob, + ) + self.repo_obj.last_imported_commit = latest_commit_hash + self.repo_obj.save() + logger.info("The Importer run successfully") + + +def vul_handler(change_type, repo_obj, yaml_data_a_blob, yaml_data_b_blob, a_path, b_path): + if change_type == "A": # A for added paths + Vulnerability.objects.get_or_create( + id=yaml_data_b_blob.get("vulnerability_id"), + repo=repo_obj, + ) + elif change_type in [ + "M", + "R", + ]: # R for renamed paths , M for paths with modified data + vul = Vulnerability.objects.get( + id=yaml_data_a_blob.get("vulnerability_id"), + repo=repo_obj, + ) + vul.filename = yaml_data_b_blob.get("vulnerability_id") + vul.save() + elif change_type == "D": # D for deleted paths + vul = Vulnerability.objects.filter( + id=yaml_data_b_blob.get("vulnerability_id"), + repo=repo_obj, + ) + vul.delete() + else: + logger.error(f"Invalid Vulnerability File") + + +def pkg_handler(change_type, default_service, yaml_data_a_blob, yaml_data_b_blob): + if change_type == "A": + package = yaml_data_b_blob.get("package") + + pkg, _ = Package.objects.get_or_create(purl=package, service=default_service) + + for version in yaml_data_b_blob.get("versions", []): + create_note(pkg, version) + + elif change_type == "M": + old_package = yaml_data_a_blob.get("package") + new_package = yaml_data_b_blob.get("package") + + pkg = Package.objects.get(purl=old_package, service=default_service) + pkg.purl = new_package + pkg.save() + + for version_a, version_b in zip_longest( + yaml_data_a_blob.get("versions", []), yaml_data_b_blob.get("versions", []) + ): + if version_b and not version_a: + create_note(pkg, version_b) + + if version_a and not version_b: + delete_note(pkg, version_a) + + if version_a and version_b: + note = Note.objects.get(acct=pkg.acct, content=saneyaml.dump(version_a)) + if note.content == saneyaml.dump(version_b): + continue + + note.content = saneyaml.dump(version_b) + note.save() + + update_activity = UpdateActivity(actor=pkg.to_ap, object=note.to_ap) + Activity.federate( + targets=pkg.followers_inboxes, + body=update_activity.to_ap(), + key_id=pkg.key_id, + ) + + elif change_type == "D": + package = yaml_data_a_blob.get("package") + pkg = Package.objects.get(purl=package, service=default_service) + for version in yaml_data_a_blob.get("versions", []): + delete_note(pkg, version) + pkg.delete() + + +def create_note(pkg, version): + note, _ = Note.objects.get_or_create(acct=pkg.acct, content=saneyaml.dump(version)) + pkg.notes.add(note) + create_activity = CreateActivity(actor=pkg.to_ap, object=note.to_ap) + Activity.federate( + targets=pkg.followers_inboxes, + body=create_activity.to_ap(), + key_id=pkg.key_id, + ) + + +def delete_note(pkg, version): + note = Note.objects.get(acct=pkg.acct, content=saneyaml.dump(version)) + note_ap = note.to_ap + note.delete() + pkg.notes.remove(note) + + deleted_activity = DeleteActivity(actor=pkg.to_ap, object=note_ap) + Activity.federate( + targets=pkg.followers_inboxes, + body=deleted_activity.to_ap, + key_id=pkg.key_id, + ) diff --git a/fedcode/management/commands/tasks.py b/fedcode/management/commands/tasks.py new file mode 100644 index 0000000..281c554 --- /dev/null +++ b/fedcode/management/commands/tasks.py @@ -0,0 +1,57 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +from fedcode.importer import Importer +from fedcode.models import FederateRequest, SyncRequest +from fedcode.signatures import HttpSignature, FEDERATED_CODE_PRIVATE_KEY +from django.core.management.base import BaseCommand, CommandError + + +def sync_task(): + """ + sync_task is a task to run the Importer and save the status + """ + for sync_r in SyncRequest.objects.all().order_by('created_at'): + if not sync_r.done: + try: + repo = sync_r.repo + repo.git_repo_obj.remotes.origin.pull() + importer = Importer(repo, repo.admin) + importer.run() + sync_r.done = True + except Exception as e: + sync_r.error_message = e + finally: + sync_r.save() + + +def send_fed_req_task(): + """ + send_fed_req_task is a task to send the http signed request to the target and save the status of the request + """ + for rq in FederateRequest.objects.all().order_by('created_at'): + if not rq.done: + try: + HttpSignature.signed_request(rq.target, rq.body, FEDERATED_CODE_PRIVATE_KEY, rq.key_id) + rq.done = True + rq.save() + except Exception as e: + rq.error_message = e + finally: + rq.save() + + +class Command(BaseCommand): + def add_arguments(self, parser): + parser.add_argument("task", choices=["sync", "federate"]) + + def handle(self, *args, **options): + if options['task'] == "sync": + sync_task() + elif options['task'] == "federate": + send_fed_req_task() diff --git a/fedcode/migrations/0001_initial.py b/fedcode/migrations/0001_initial.py new file mode 100644 index 0000000..ec3e986 --- /dev/null +++ b/fedcode/migrations/0001_initial.py @@ -0,0 +1,484 @@ +# Generated by Django 5.0.1 on 2024-03-02 15:54 + +import django.db.models.deletion +import uuid +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("contenttypes", "0002_remove_content_type_name"), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="FederateRequest", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ( + "target", + models.URLField( + help_text="The request target ex: (inbox of the targeted actor" + ), + ), + ("body", models.TextField(help_text="The request body")), + ( + "key_id", + models.URLField( + help_text="The key url of the actor ex: https://my-example.com/actor#main-key" + ), + ), + ("error_message", models.TextField()), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, help_text="A field to track when review are created" + ), + ), + ("done", models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name="RemoteActor", + fields=[ + ("url", models.URLField(primary_key=True, serialize=False)), + ("username", models.CharField(max_length=100)), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, + help_text="A field to track when remote actor are created", + ), + ), + ( + "updated_at", + models.DateTimeField( + auto_now=True, help_text="A field to track when remote actor are updated" + ), + ), + ], + ), + migrations.CreateModel( + name="Repository", + fields=[ + ( + "id", + models.UUIDField( + default=uuid.uuid4, + editable=False, + help_text="The object's unique global identifier", + primary_key=True, + serialize=False, + ), + ), + ( + "url", + models.URLField( + help_text="Git Repository url ex: https://github.com/nexB/vulnerablecode-data" + ), + ), + ("path", models.CharField(help_text="path of the repository", max_length=200)), + ( + "remote_url", + models.CharField( + blank=True, + help_text="the url of the repository if this repository is remote", + max_length=300, + null=True, + ), + ), + ("last_imported_commit", models.CharField(blank=True, max_length=64, null=True)), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, help_text="A field to track when repository are created" + ), + ), + ( + "updated_at", + models.DateTimeField( + auto_now=True, help_text="A field to track when repository are updated" + ), + ), + ], + options={ + "ordering": ["-updated_at"], + }, + ), + migrations.CreateModel( + name="Note", + fields=[ + ( + "id", + models.UUIDField( + default=uuid.uuid4, + editable=False, + help_text="The object's unique global identifier", + primary_key=True, + serialize=False, + ), + ), + ("acct", models.CharField(max_length=200)), + ("content", models.TextField()), + ("mediaType", models.CharField(default="text/plain", max_length=20)), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, help_text="A field to track when notes are created" + ), + ), + ( + "updated_at", + models.DateTimeField( + auto_now=True, help_text="A field to track when notes are updated" + ), + ), + ( + "reply_to", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="replies", + to="fedcode.note", + ), + ), + ], + options={ + "ordering": ["-updated_at"], + }, + ), + migrations.CreateModel( + name="Package", + fields=[ + ("summary", models.CharField(help_text="profile summary", max_length=100)), + ("public_key", models.TextField()), + ("local", models.BooleanField(default=True)), + ( + "id", + models.UUIDField( + default=uuid.uuid4, + editable=False, + help_text="The object's unique global identifier", + primary_key=True, + serialize=False, + ), + ), + ( + "purl", + models.CharField( + help_text="PURL (no version) ex: @pkg:maven/org.apache.logging", + max_length=300, + unique=True, + ), + ), + ( + "notes", + models.ManyToManyField( + blank=True, + help_text="the notes that this purl created ex:\n purl: pkg:.../.../\n affected_by_vulnerabilities: []\n fixing_vulnerabilities: []\n ", + to="fedcode.note", + ), + ), + ( + "remote_actor", + models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="fedcode.remoteactor", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Person", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("summary", models.CharField(help_text="profile summary", max_length=100)), + ("public_key", models.TextField()), + ("local", models.BooleanField(default=True)), + ( + "avatar", + models.ImageField(default="favicon-16x16.png", null=True, upload_to="uploads/"), + ), + ("notes", models.ManyToManyField(blank=True, to="fedcode.note")), + ( + "user", + models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "remote_actor", + models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="fedcode.remoteactor", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Follow", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "package", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="fedcode.package" + ), + ), + ( + "person", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="fedcode.person" + ), + ), + ], + options={ + "ordering": ["-updated_at"], + }, + ), + migrations.CreateModel( + name="Review", + fields=[ + ( + "id", + models.UUIDField( + default=uuid.uuid4, + editable=False, + help_text="The object's unique global identifier", + primary_key=True, + serialize=False, + ), + ), + ("headline", models.CharField(help_text="the review title", max_length=300)), + ( + "filepath", + models.CharField( + help_text="the review path ex: /apache/httpd/VCID-1a68-fd5t-aaam.yml", + max_length=300, + ), + ), + ( + "commit", + models.CharField( + help_text="ex: 104ccd6a7a41329b2953c96e52792a3d6a9ad8e5", max_length=300 + ), + ), + ("data", models.TextField(help_text="review data ex: vulnerability file")), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, help_text="A field to track when review are created" + ), + ), + ( + "updated_at", + models.DateTimeField( + auto_now=True, help_text="A field to track when review are updated" + ), + ), + ( + "remote_url", + models.CharField( + blank=True, + help_text="the review remote url if Remote Review exists", + max_length=300, + null=True, + ), + ), + ( + "status", + models.SmallIntegerField( + choices=[(0, "Open"), (1, "Draft"), (2, "Closed"), (3, "Merged")], + default=0, + help_text="status of review", + ), + ), + ( + "author", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="fedcode.person" + ), + ), + ("notes", models.ManyToManyField(blank=True, to="fedcode.note")), + ( + "repository", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="fedcode.repository" + ), + ), + ], + options={ + "ordering": ["-updated_at"], + }, + ), + migrations.CreateModel( + name="Service", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ( + "remote_actor", + models.OneToOneField( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="fedcode.remoteactor", + ), + ), + ( + "user", + models.OneToOneField( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.AddField( + model_name="repository", + name="admin", + field=models.ForeignKey( + help_text="admin user ex: VCIO user", + on_delete=django.db.models.deletion.CASCADE, + to="fedcode.service", + ), + ), + migrations.AddField( + model_name="package", + name="service", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="fedcode.service", + ), + ), + migrations.CreateModel( + name="SyncRequest", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("error_message", models.TextField()), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, help_text="A field to track when review are created" + ), + ), + ("done", models.BooleanField(default=False)), + ( + "repo", + models.ForeignKey( + help_text="The Git repository where the importer will run", + on_delete=django.db.models.deletion.CASCADE, + to="fedcode.repository", + ), + ), + ], + ), + migrations.CreateModel( + name="Reputation", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ("voter", models.CharField(help_text="security@vcio", max_length=100)), + ("positive", models.BooleanField(default=True)), + ("object_id", models.UUIDField(blank=True, db_index=True, null=True)), + ( + "content_type", + models.ForeignKey( + limit_choices_to=models.Q( + models.Q(("app_label", "fedcode"), ("model", "review")), + models.Q(("app_label", "fedcode"), ("model", "note")), + _connector="OR", + ), + on_delete=django.db.models.deletion.CASCADE, + to="contenttypes.contenttype", + ), + ), + ], + options={ + "indexes": [ + models.Index( + fields=["content_type", "object_id"], name="fedcode_rep_content_8b327e_idx" + ) + ], + "unique_together": {("voter", "content_type", "object_id")}, + }, + ), + migrations.AlterUniqueTogether( + name="repository", + unique_together={("admin", "url")}, + ), + migrations.CreateModel( + name="Vulnerability", + fields=[ + ( + "id", + models.CharField( + help_text="Unique identifier for a vulnerability in the external representation. It is prefixed with VCID-", + max_length=20, + primary_key=True, + serialize=False, + ), + ), + ("remote_url", models.CharField(blank=True, max_length=300, null=True)), + ( + "repo", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="fedcode.repository" + ), + ), + ], + options={ + "unique_together": {("repo",)}, + }, + ), + ] diff --git a/fedcode/migrations/__init__.py b/fedcode/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fedcode/models.py b/fedcode/models.py new file mode 100644 index 0000000..9904826 --- /dev/null +++ b/fedcode/models.py @@ -0,0 +1,538 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +import uuid + +from django.contrib.auth.models import User +from django.contrib.contenttypes.models import ContentType +from django.db import models +from django.db.models.signals import post_save +from django.dispatch import receiver +from git import Repo + +from fedcode.utils import ap_collection, clone_git_repo +from fedcode.utils import full_reverse +from fedcode.utils import generate_webfinger +from federatedcode.settings import FEDERATED_CODE_DOMAIN +from federatedcode.settings import FEDERATED_CODE_GIT_PATH +from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation + + +class RemoteActor(models.Model): + url = models.URLField(primary_key=True) + username = models.CharField(max_length=100) + created_at = models.DateTimeField( + auto_now_add=True, help_text="A field to track when remote actor are created" + ) + updated_at = models.DateTimeField( + auto_now=True, help_text="A field to track when remote actor are updated" + ) + + +class Actor(models.Model): + summary = models.CharField(help_text="profile summary", max_length=100) + public_key = models.TextField(blank=False) + local = models.BooleanField(default=True) + + class Meta: + abstract = True + + +class Reputation(models.Model): + """ + https://www.w3.org/TR/activitystreams-vocabulary/#dfn-like + https://www.w3.org/ns/activitystreams#Dislike + """ + voter = models.CharField(max_length=100, help_text="security@vcio") + positive = models.BooleanField(default=True) # Like vs Dislike + limit = (models.Q(app_label='fedcode', model='review') | + models.Q(app_label='fedcode', model='note')) + + content_type = models.ForeignKey( + ContentType, + limit_choices_to=limit, + on_delete=models.CASCADE + ) + object_id = models.UUIDField( + null=True, + blank=True, + db_index=True + ) + content_object = GenericForeignKey('content_type', 'object_id') + + @property + def to_ap(self): + return { + "type": "Like" if self.positive else "Dislike", + "actor": self.voter, + "object": self.content_object.to_ap + } + + class Meta: + unique_together = [["voter", "content_type", "object_id"]] + indexes = [ + models.Index(fields=["content_type", "object_id"]), + ] + + +class Service(models.Model): + """ + A AdminUser is a special user that can manage git repositories ( sync , create ) + """ + user = models.OneToOneField(User, null=True, on_delete=models.CASCADE) + remote_actor = models.OneToOneField( + RemoteActor, on_delete=models.CASCADE, null=True, blank=True + ) + + def __str__(self): + return self.user.username if self.user else self.remote_actor.username + + @property + def absolute_url_ap(self): + return full_reverse("user-ap-profile", self.user.username) + + @property + def to_ap(self): + return { + "type": "Service", # TODO + "name": self.user.username, + } + + +class Note(models.Model): + """ + A Note is a message send by a Person or Package. + The content is either a plain text message or structured YAML. + If the author is a Package actor then the content is always YAML + If the author is a Person actor then the content is always plain text + https://www.w3.org/TR/activitystreams-vocabulary/#dfn-note + """ + # https://www.w3.org/TR/activitystreams-vocabulary/#dfn-mediatype + id = models.UUIDField( + primary_key=True, + editable=False, + default=uuid.uuid4, + help_text="The object's unique global identifier", + ) + acct = models.CharField(max_length=200) + content = models.TextField() + reply_to = models.ForeignKey( + "self", + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="replies", + help_text="", + ) + mediaType = models.CharField(max_length=20, default="text/plain") + created_at = models.DateTimeField( + auto_now_add=True, help_text="A field to track when notes are created" + ) + updated_at = models.DateTimeField( + auto_now=True, help_text="A field to track when notes are updated" + ) + + reputation = GenericRelation(Reputation) + + class Meta: + ordering = ["-updated_at"] + + @property + def username(self): + return self.acct.split("@")[0] + + @property + def reputation_value(self): + return ( + self.reputation.filter(positive=True).count() + - self.reputation.filter(positive=False).count() + ) + + @property + def absolute_url(self): + return full_reverse("note-page", self.id) + + @property + def to_ap(self): + return { + "id": self.absolute_url, + "type": "Note", + "author": self.acct, + "content": self.content, + } + + +class Package(Actor): + """ + A software package identified by its package url ( PURL ) ignoring versions + """ + id = models.UUIDField( + primary_key=True, + default=uuid.uuid4, + editable=False, + help_text="The object's unique global identifier", + ) + remote_actor = models.OneToOneField( + RemoteActor, on_delete=models.CASCADE, null=True, blank=True + ) + service = models.ForeignKey(Service, null=True, blank=True, on_delete=models.CASCADE) + purl = models.CharField( + max_length=300, help_text="PURL (no version) ex: @pkg:maven/org.apache.logging", unique=True, + ) + notes = models.ManyToManyField(Note, blank=True, help_text="""the notes that this purl created ex: + purl: pkg:.../.../ + affected_by_vulnerabilities: [] + fixing_vulnerabilities: [] + """) + + @property + def acct(self): + return generate_webfinger(self.purl) + + def __str__(self): + return self.purl + + @property + def followers_count(self): + return Follow.objects.filter(package=self).count() + + @property + def followers(self): + return Follow.objects.filter(package=self).values("person_id") + + @property + def followers_inboxes(self): + """Return a followers inbox list""" + # TODO Try to avoid for loop + inboxes = [] + for person in self.followers: + person_inbox = Person.objects.get(id=person["person_id"]).inbox_url + inboxes.append(person_inbox) + return inboxes + + # TODO raise error if the package have a version or qualifiers or subpath + # def save(self, *args, **kwargs): + # if not check_purl_actor(self.string): + # return ValidationError(self.string) + # super(Purl, self).save(*args, **kwargs) + + @property + def absolute_url_ap(self): + return full_reverse("purl-ap-profile", self.purl) + + @property + def inbox_url(self): + return full_reverse("purl-inbox", self.purl) + + @property + def outbox_url(self): + return full_reverse("purl-outbox", self.purl) + + @property + def followers_url(self): + return full_reverse("purl-followers", self.purl) + + @property + def key_id(self): + return full_reverse("purl-ap-profile", self.purl) + + @property + def to_ap(self): + return { + "id": self.absolute_url_ap, + "type": "Package", + "name": self.service.user.username, + "purl": self.purl, + "inbox": self.inbox_url, + "outbox": self.outbox_url, + "followers": self.followers_url, + "publicKey": { + "id": self.absolute_url_ap, + "owner": self.service.absolute_url_ap, + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", + }, + } + + +class Person(Actor): + """ + A person is a user can follow pacakge or just vote or create a notes + """ + avatar = models.ImageField( + upload_to="uploads/", help_text="", default="favicon-16x16.png", null=True + ) + user = models.OneToOneField(User, null=True, on_delete=models.CASCADE) + remote_actor = models.OneToOneField( + RemoteActor, on_delete=models.CASCADE, null=True, blank=True + ) + + notes = models.ManyToManyField(Note, blank=True, help_text="") + + @property + def avatar_absolute_url(self): + return f'{"https://"}{FEDERATED_CODE_DOMAIN}{self.avatar.url}' + + # TODO raise error if the user doesn't have a user or remote actor + @property + def reputation_value(self): + """if someone like your ( review or note ) you will get +1, dislike: -1""" + # user_reputation = Reputation.objects.filter(voter=self.acct) + # return ( + # user_reputation.filter(positive=True).count() + # - user_reputation.filter(positive=False).count() + # ) + return 0 # FIXME + + @property + def acct(self): + return generate_webfinger(self.user.username) + + @property + def url(self): + return full_reverse("user-profile", self.user.username) + + @property + def absolute_url_ap(self): + return full_reverse("user-ap-profile", self.user.username) + + @property + def inbox_url(self): + return full_reverse("user-inbox", self.user.username) + + @property + def outbox_url(self): + return full_reverse("user-outbox", self.user.username) + + @property + def following_url(self): + return full_reverse("user-following", self.user.username) + + @property + def key_id(self): + if self.user: + return full_reverse("user-ap-profile", self.user.username) + "#main-key" + else: + return self.remote_actor.url + "#main-key" + + @property + def to_ap(self): + return { + "id": self.absolute_url_ap, + "type": "Person", + "name": self.user.username, + "summary": self.summary, + "inbox": self.inbox_url, + "outbox": self.outbox_url, + "following": self.following_url, + "image": self.avatar_absolute_url, + "publicKey": { + "id": self.absolute_url_ap, + "owner": self.absolute_url_ap, + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", + }, + } + + +class Follow(models.Model): + person = models.ForeignKey(Person, on_delete=models.CASCADE, help_text="") + package = models.ForeignKey(Package, on_delete=models.CASCADE, help_text="") + created_at = models.DateTimeField(auto_now_add=True, help_text="") + updated_at = models.DateTimeField(auto_now=True, help_text="") + + class Meta: + ordering = ["-updated_at"] + + def __str__(self): + return f"{self.person.user.username} - {self.package.purl}" + + +class Repository(models.Model): # TODO + """ + A git repository used as a backing storage for Package and vulnerability data + """ + id = models.UUIDField( + primary_key=True, + editable=False, + default=uuid.uuid4, + help_text="The object's unique global identifier", + ) + url = models.URLField(help_text="Git Repository url ex: https://github.com/nexB/vulnerablecode-data") + path = models.CharField(max_length=200, help_text="path of the repository") + admin = models.ForeignKey(Service, on_delete=models.CASCADE, help_text="admin user ex: VCIO user") # + remote_url = models.CharField(max_length=300, blank=True, null=True, help_text="the url of the repository" + " if this repository is remote") + last_imported_commit = models.CharField(max_length=64, blank=True, null=True) + + created_at = models.DateTimeField( + auto_now_add=True, help_text="A field to track when repository are created" + ) + updated_at = models.DateTimeField( + auto_now=True, help_text="A field to track when repository are updated" + ) + + def __str__(self): + return self.url + + @property + def review_count(self): + return Review.objects.filter(repository=self).count() + + @property + def git_repo_obj(self): + return Repo(self.path) + + class Meta: + unique_together = [["admin", "url"]] + ordering = ["-updated_at"] + + @property + def absolute_url(self): + return full_reverse("repository-page", self.id) + + @property + def to_ap(self): + return { + "id": self.absolute_url, + "type": "Repository", + "url": self.url, + } + + +class Vulnerability(models.Model): + id = models.CharField( + primary_key=True, + max_length=20, + help_text="Unique identifier for a vulnerability in the external representation. " + "It is prefixed with VCID-", + ) + + repo = models.ForeignKey(Repository, on_delete=models.CASCADE) + remote_url = models.CharField(max_length=300, blank=True, null=True, help_text="") + + class Meta: + unique_together = [["repo"]] + + @property + def absolute_url(self): + return full_reverse("vulnerability-page", self.id) + + def __str__(self): + return self.id + + @property + def to_ap(self): + return { + "id": self.absolute_url, + "type": "Vulnerability", + "repository": self.repo.absolute_url, + } + + +class Review(models.Model): + # TODO + id = models.UUIDField( + primary_key=True, + editable=False, + default=uuid.uuid4, + help_text="The object's unique global identifier", + ) + headline = models.CharField(max_length=300, help_text="the review title") + author = models.ForeignKey(Person, on_delete=models.CASCADE) + repository = models.ForeignKey(Repository, on_delete=models.CASCADE) + filepath = models.CharField(max_length=300, help_text="the review path ex: /apache/httpd/VCID-1a68-fd5t-aaam.yml") + commit = models.CharField(max_length=300, help_text="ex: 104ccd6a7a41329b2953c96e52792a3d6a9ad8e5") + data = models.TextField(help_text="review data ex: vulnerability file") + notes = models.ManyToManyField(Note, blank=True, help_text="") + created_at = models.DateTimeField( + auto_now_add=True, help_text="A field to track when review are created" + ) + updated_at = models.DateTimeField( + auto_now=True, help_text="A field to track when review are updated" + ) + remote_url = models.CharField(max_length=300, blank=True, null=True, help_text="the review remote url if " + "Remote Review exists") + + class ReviewStatus(models.IntegerChoices): + OPEN = 0 + DRAFT = 1 + CLOSED = 2 + MERGED = 3 + + status = models.SmallIntegerField( + choices=ReviewStatus.choices, + null=False, + blank=False, + default=0, + help_text="status of review", + ) + reputation = GenericRelation(Reputation) + + class Meta: + ordering = ["-updated_at"] + + def __str__(self): + return f"{self.headline}" + + @property + def reputation_value(self): + return ( + self.reputation.filter(positive=True).count() + - self.reputation.filter(positive=False).count() + ) + + @property + def absolute_url(self): + return full_reverse("review-page", self.id) + + @property + def to_ap(self): + return { + "id": self.absolute_url, + "type": "Review", + "author": self.author.absolute_url_ap, + "headline": self.headline, + "repository": str(self.repository.id), + "filepath": self.filepath, + "commit": self.commit, + "content": self.data, + "comments": ap_collection(self.notes), + "published": self.created_at, + "updated": self.updated_at, + } + + +class FederateRequest(models.Model): + target = models.URLField(help_text="The request target ex: (inbox of the targeted actor", blank=False, null=False) + body = models.TextField(help_text="The request body", blank=False, null=False) + key_id = models.URLField(help_text="The key url of the actor ex: https://my-example.com/actor#main-key", + blank=False, null=False) + error_message = models.TextField() + created_at = models.DateTimeField( + auto_now_add=True, help_text="A field to track when review are created" + ) + done = models.BooleanField(default=False) + + +class SyncRequest(models.Model): + repo = models.ForeignKey(Repository, on_delete=models.CASCADE, + help_text="The Git repository where the importer will run" + ) + error_message = models.TextField() + created_at = models.DateTimeField( + auto_now_add=True, help_text="A field to track when review are created" + ) + done = models.BooleanField(default=False) + + +@receiver(post_save, sender=Repository) +def create_git_repo(sender, instance, created, **kwargs): + if created: + repo = clone_git_repo(FEDERATED_CODE_GIT_PATH, instance.url) + instance.path = repo.working_dir + instance.save() diff --git a/fedcode/signatures.py b/fedcode/signatures.py new file mode 100644 index 0000000..da8b0b5 --- /dev/null +++ b/fedcode/signatures.py @@ -0,0 +1,381 @@ +import base64 +import json +from ssl import SSLCertVerificationError +from ssl import SSLError +from typing import Literal +from typing import TypedDict +from typing import cast +from urllib.parse import urlparse + +import httpx +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives.asymmetric import rsa +from django.conf import settings +from django.http import HttpRequest +from django.utils import timezone +from django.utils.http import http_date +from django.utils.http import parse_http_date +from httpx._types import TimeoutTypes +from idna.core import InvalidCodepoint + +# from pyld import jsonld +# +# from core.ld import format_ld_date + + +class VerificationError(BaseException): + """ + There was an error with verifying the signature + """ + + pass + + +class VerificationFormatError(VerificationError): + """ + There was an error with the format of the signature (not if it is valid) + """ + + pass + + +class RsaKeys: + @classmethod + def generate_keypair(cls) -> tuple[str, str]: + """ + Generates a new RSA keypair + """ + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + ) + private_key_serialized = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption(), + ).decode("ascii") + public_key_serialized = ( + private_key.public_key() + .public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo, + ) + .decode("ascii") + ) + return private_key_serialized, public_key_serialized + + +FEDERATED_CODE_PRIVATE_KEY, FEDERATED_CODE_PUBLIC_KEY = RsaKeys.generate_keypair() + + +class HttpSignature: + """ + Allows for calculation and verification of HTTP signatures + """ + + @classmethod + def calculate_digest(cls, data, algorithm="sha-256") -> str: + """ + Calculates the digest header value for a given HTTP body + """ + if algorithm == "sha-256": + digest = hashes.Hash(hashes.SHA256()) + digest.update(data) + return "SHA-256=" + base64.b64encode(digest.finalize()).decode("ascii") + else: + raise ValueError(f"Unknown digest algorithm {algorithm}") + + @classmethod + def headers_from_request(cls, request: HttpRequest, header_names: list[str]) -> str: + """ + Creates the to-be-signed header payload from a Django request + """ + headers = {} + for header_name in header_names: + if header_name == "(request-target)": + value = f"{request.method.lower()} {request.path}" + elif header_name == "content-type": + value = request.headers["content-type"] + elif header_name == "content-length": + value = request.headers["content-length"] + else: + value = request.META["HTTP_%s" % header_name.upper().replace("-", "_")] + headers[header_name] = value + return "\n".join(f"{name.lower()}: {value}" for name, value in headers.items()) + + @classmethod + def parse_signature(cls, signature: str) -> "HttpSignatureDetails": + bits = {} + for item in signature.split(","): + name, value = item.split("=", 1) + value = value.strip('"') + bits[name.lower()] = value + try: + signature_details: HttpSignatureDetails = { + "headers": bits["headers"].split(), + "signature": base64.b64decode(bits["signature"]), + "algorithm": bits["algorithm"], + "keyid": bits["keyid"], + } + except KeyError as e: + key_names = " ".join(bits.keys()) + raise VerificationError(f"Missing item from details (have: {key_names}, error: {e})") + return signature_details + + @classmethod + def compile_signature(cls, details: "HttpSignatureDetails") -> str: + value = f'keyId="{details["keyid"]}",headers="' + value += " ".join(h.lower() for h in details["headers"]) + value += '",signature="' + value += base64.b64encode(details["signature"]).decode("ascii") + value += f'",algorithm="{details["algorithm"]}"' + return value + + @classmethod + def verify_signature( + cls, + signature: bytes, + cleartext: str, + public_key: str, + ): + public_key_instance: rsa.RSAPublicKey = cast( + rsa.RSAPublicKey, + serialization.load_pem_public_key(public_key.encode("ascii")), + ) + try: + public_key_instance.verify( + signature, + cleartext.encode("utf8"), + padding.PKCS1v15(), + hashes.SHA256(), + ) + except InvalidSignature: + raise VerificationError("Signature mismatch") + + @classmethod + def verify_request(cls, request, public_key, skip_date=False): + """ + Verifies that the request has a valid signature for its body + """ + # Verify body digest + if "digest" in request.headers: + expected_digest = HttpSignature.calculate_digest(request.body) + if request.headers["digest"] != expected_digest: + raise VerificationFormatError("Digest is incorrect") + # Verify date header + if "date" in request.headers and not skip_date: + header_date = parse_http_date(request.headers["date"]) + if abs(timezone.now().timestamp() - header_date) > 60: + raise VerificationFormatError("Date is too far away") + # Get the signature details + if "signature" not in request.headers: + raise VerificationFormatError("No signature header present") + signature_details = cls.parse_signature(request.headers["signature"]) + # Reject unknown algorithms + # hs2019 is used by some libraries to obfuscate the real algorithm per the spec + # https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12 + if ( + signature_details["algorithm"] != "rsa-sha256" + and signature_details["algorithm"] != "hs2019" + ): + raise VerificationFormatError("Unknown signature algorithm") + # Create the signature payload + headers_string = cls.headers_from_request(request, signature_details["headers"]) + cls.verify_signature( + signature_details["signature"], + headers_string, + public_key, + ) + + @classmethod + def signed_request( + cls, + uri: str, + body: dict | None, + private_key: str, + key_id: str, + content_type: str = "application/json", + method: Literal["get", "post"] = "post", + # timeout: TimeoutTypes = settings.SETUP.REMOTE_TIMEOUT, + ): + """ + Performs an async request to the given path, with a document, signed + as an identity. + """ + if "://" not in uri: + raise ValueError("URI does not contain a scheme") + # Create the core header field set + uri_parts = urlparse(uri) + date_string = http_date() + headers = { + "(request-target)": f"{method} {uri_parts.path}", + "Host": uri_parts.hostname, + "Date": date_string, + } + # If we have a body, add a digest and content type + if body is not None: + body_bytes = json.dumps(body).encode("utf8") + headers["Digest"] = cls.calculate_digest(body_bytes) + headers["Content-Type"] = content_type + else: + body_bytes = b"" + # GET requests get implicit accept headers added + if method == "get": + headers["Accept"] = "application/ld+json" + # Sign the headers + signed_string = "\n".join(f"{name.lower()}: {value}" for name, value in headers.items()) + private_key_instance: rsa.RSAPrivateKey = cast( + rsa.RSAPrivateKey, + serialization.load_pem_private_key( + private_key.encode("ascii"), + password=None, + ), + ) + signature = private_key_instance.sign( + signed_string.encode("utf8"), + padding.PKCS1v15(), + hashes.SHA256(), + ) + headers["Signature"] = cls.compile_signature( + { + "keyid": key_id, + "headers": list(headers.keys()), + "signature": signature, + "algorithm": "rsa-sha256", + } + ) + + # Announce ourselves with an agent similar to Mastodon + # headers["User-Agent"] = settings.TAKAHE_USER_AGENT + + # Send the request with all those headers except the pseudo one + del headers["(request-target)"] + with httpx.Client() as client: + try: + response = client.request( + method, + uri, + headers=headers, + content=body_bytes, + follow_redirects=method == "get", + ) + except SSLError as invalid_cert: + # Not our problem if the other end doesn't have proper SSL + print(f"{uri} {invalid_cert}") + raise SSLCertVerificationError(invalid_cert) from invalid_cert + except InvalidCodepoint as ex: + # Convert to a more generic error we handle + raise httpx.HTTPError(f"InvalidCodepoint: {str(ex)}") from None + + if ( + method == "post" + # and 400 <= response.status_code < 500 + # and response.status_code != 404 + and response.status_code == 200 + ): + raise ValueError( + f"POST error to {uri}: {response.status_code} {response.content!r}" + ) + return response + + +class HttpSignatureDetails(TypedDict): + algorithm: str + headers: list[str] + signature: bytes + keyid: str + + +# class LDSignature: +# """ +# Creates and verifies signatures of JSON-LD documents +# """ +# +# @classmethod +# def verify_signature(cls, document: dict, public_key: str) -> None: +# """ +# Verifies a document +# """ +# try: +# # Strip out the signature from the incoming document +# signature = document.pop("signature") +# # Create the options document +# options = { +# "@context": "https://w3id.org/identity/v1", +# "creator": signature["creator"], +# "created": signature["created"], +# } +# except KeyError: +# raise VerificationFormatError("Invalid signature section") +# if signature["type"].lower() != "rsasignature2017": +# raise VerificationFormatError("Unknown signature type") +# # Get the normalised hash of each document +# final_hash = cls.normalized_hash(options) + cls.normalized_hash(document) +# # Verify the signature +# public_key_instance: rsa.RSAPublicKey = cast( +# rsa.RSAPublicKey, +# serialization.load_pem_public_key(public_key.encode("ascii")), +# ) +# try: +# public_key_instance.verify( +# base64.b64decode(signature["signatureValue"]), +# final_hash, +# padding.PKCS1v15(), +# hashes.SHA256(), +# ) +# except InvalidSignature: +# raise VerificationError("Signature mismatch") +# +# @classmethod +# def create_signature( +# cls, document: dict, private_key: str, key_id: str +# ) -> dict[str, str]: +# """ +# Creates the signature for a document +# """ +# # Create the options document +# options: dict[str, str] = { +# "@context": "https://w3id.org/identity/v1", +# "creator": key_id, +# "created": format_ld_date(timezone.now()), +# } +# # Get the normalised hash of each document +# final_hash = cls.normalized_hash(options) + cls.normalized_hash(document) +# # Create the signature +# private_key_instance: rsa.RSAPrivateKey = cast( +# rsa.RSAPrivateKey, +# serialization.load_pem_private_key( +# private_key.encode("ascii"), +# password=None, +# ), +# ) +# signature = base64.b64encode( +# private_key_instance.sign( +# final_hash, +# padding.PKCS1v15(), +# hashes.SHA256(), +# ) +# ) +# # Add it to the options document along with other bits +# options["signatureValue"] = signature.decode("ascii") +# options["type"] = "RsaSignature2017" +# return options +# +# @classmethod +# def normalized_hash(cls, document) -> bytes: +# """ +# Takes a JSON-LD document and create a hash of its URDNA2015 form, +# in the same way that Mastodon does internally. +# +# Reference: https://socialhub.activitypub.rocks/t/making-sense-of-rsasignature2017/347 +# """ +# norm_form = jsonld.normalize( +# document, +# {"algorithm": "URDNA2015", "format": "application/n-quads"}, +# ) +# digest = hashes.Hash(hashes.SHA256()) +# digest.update(norm_form.encode("utf8")) +# return digest.finalize().hex().encode("ascii") diff --git a/fedcode/signatures.py.ABOUT b/fedcode/signatures.py.ABOUT new file mode 100644 index 0000000..70bcce5 --- /dev/null +++ b/fedcode/signatures.py.ABOUT @@ -0,0 +1,3 @@ +download_url: https://github.com/jointakahe/takahe/blob/2a50928f27701212e05862376e9ab478d1a01654/core/signatures.py +license_expression: BSD-3-Clause +license_file: signatures.py.LICENSE \ No newline at end of file diff --git a/fedcode/signatures.py.LICENSE b/fedcode/signatures.py.LICENSE new file mode 100644 index 0000000..1d2156a --- /dev/null +++ b/fedcode/signatures.py.LICENSE @@ -0,0 +1,26 @@ +Copyright 2022 Andrew Godwin + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/fedcode/static/css/bulma-tooltip.css b/fedcode/static/css/bulma-tooltip.css new file mode 100644 index 0000000..200345f --- /dev/null +++ b/fedcode/static/css/bulma-tooltip.css @@ -0,0 +1,2506 @@ +/*! @creativebulma/bulma-tooltip v1.2.0 | (c) 2020 Gaetan | MIT License | https://github.com/CreativeBulma/bulma-tooltip */ +@-webkit-keyframes spinAround { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(359deg); + } +} + +@keyframes spinAround { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(359deg); + } +} + +/* line 67, src/sass/app.sass */ +[data-tooltip]:not(.is-loading), +[data-tooltip]:not(.is-disabled), +[data-tooltip]:not([disabled]) { + cursor: pointer; + overflow: visible; + position: relative; +} + +/* line 36, src/sass/app.sass */ +[data-tooltip]:not(.is-loading)::before, +[data-tooltip]:not(.is-disabled)::before, +[data-tooltip]:not([disabled])::before { + box-sizing: border-box; + color: white; + display: inline-block; + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif; + font-size: 0.75rem; + -webkit-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto; + opacity: 0; + overflow: hidden; + pointer-events: none; + position: absolute; + visibility: hidden; + z-index: 1020; + background: rgba(74, 74, 74, 0.9); + border-radius: 2px; + content: attr(data-tooltip); + padding: 0.5rem 1rem; + text-overflow: ellipsis; + white-space: pre-line; +} + +/* line 22, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading)::before, +[data-tooltip]:not(.is-disabled)::before, +[data-tooltip]:not([disabled])::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); +} + +/* line 15, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-arrow::after, +[data-tooltip]:not(.is-disabled).has-tooltip-arrow::after, +[data-tooltip]:not([disabled]).has-tooltip-arrow::after { + box-sizing: border-box; + color: white; + display: inline-block; + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif; + font-size: 0.75rem; + -webkit-hyphens: auto; + -ms-hyphens: auto; + hyphens: auto; + opacity: 0; + overflow: hidden; + pointer-events: none; + position: absolute; + visibility: hidden; + z-index: 1020; + content: ''; + border-style: solid; + border-width: 6px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + margin-bottom: -5px; +} + +/* line 10, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-arrow.has-tooltip-arrow::after, +[data-tooltip]:not(.is-disabled).has-tooltip-arrow.has-tooltip-arrow::after, +[data-tooltip]:not([disabled]).has-tooltip-arrow.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; +} + +/* line 38, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-bottom.has-tooltip-arrow::after, +[data-tooltip]:not(.is-disabled).has-tooltip-bottom.has-tooltip-arrow::after, +[data-tooltip]:not([disabled]).has-tooltip-bottom.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; +} + +/* line 50, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-bottom::before, +[data-tooltip]:not(.is-disabled).has-tooltip-bottom::before, +[data-tooltip]:not([disabled]).has-tooltip-bottom::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); +} + +/* line 66, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-left.has-tooltip-arrow::after, +[data-tooltip]:not(.is-disabled).has-tooltip-left.has-tooltip-arrow::after, +[data-tooltip]:not([disabled]).has-tooltip-left.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); +} + +/* line 78, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-left::before, +[data-tooltip]:not(.is-disabled).has-tooltip-left::before, +[data-tooltip]:not([disabled]).has-tooltip-left::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); +} + +/* line 92, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-right.has-tooltip-arrow::after, +[data-tooltip]:not(.is-disabled).has-tooltip-right.has-tooltip-arrow::after, +[data-tooltip]:not([disabled]).has-tooltip-right.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; +} + +/* line 104, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-right::before, +[data-tooltip]:not(.is-disabled).has-tooltip-right::before, +[data-tooltip]:not([disabled]).has-tooltip-right::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); +} + +/* line 58, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-multiline::before, +[data-tooltip]:not(.is-disabled).has-tooltip-multiline::before, +[data-tooltip]:not([disabled]).has-tooltip-multiline::before { + height: auto; + width: 15rem; + max-width: 15rem; + text-overflow: clip; + white-space: normal; + word-break: keep-all; +} + +/* line 91, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-text-left::before, +[data-tooltip]:not(.is-disabled).has-tooltip-text-left::before, +[data-tooltip]:not([disabled]).has-tooltip-text-left::before { + text-align: left; +} + +/* line 94, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-text-centered::before, +[data-tooltip]:not(.is-disabled).has-tooltip-text-centered::before, +[data-tooltip]:not([disabled]).has-tooltip-text-centered::before { + text-align: center; +} + +/* line 97, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-text-right::before, +[data-tooltip]:not(.is-disabled).has-tooltip-text-right::before, +[data-tooltip]:not([disabled]).has-tooltip-text-right::before { + text-align: right; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-white::after, +[data-tooltip]:not(.is-disabled).has-tooltip-white::after, +[data-tooltip]:not([disabled]).has-tooltip-white::after { + border-color: rgba(255, 255, 255, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-white.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-white.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-white.has-tooltip-bottom::after { + border-color: transparent transparent rgba(255, 255, 255, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-white.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-white.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-white.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(255, 255, 255, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-white.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-white.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-white.has-tooltip-right::after { + border-color: transparent rgba(255, 255, 255, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-white:before, +[data-tooltip]:not(.is-disabled).has-tooltip-white:before, +[data-tooltip]:not([disabled]).has-tooltip-white:before { + background-color: rgba(255, 255, 255, 0.9); + color: #0a0a0a; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-black::after, +[data-tooltip]:not(.is-disabled).has-tooltip-black::after, +[data-tooltip]:not([disabled]).has-tooltip-black::after { + border-color: rgba(10, 10, 10, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-black.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-black.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-black.has-tooltip-bottom::after { + border-color: transparent transparent rgba(10, 10, 10, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-black.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-black.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-black.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(10, 10, 10, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-black.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-black.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-black.has-tooltip-right::after { + border-color: transparent rgba(10, 10, 10, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-black:before, +[data-tooltip]:not(.is-disabled).has-tooltip-black:before, +[data-tooltip]:not([disabled]).has-tooltip-black:before { + background-color: rgba(10, 10, 10, 0.9); + color: white; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-light::after, +[data-tooltip]:not(.is-disabled).has-tooltip-light::after, +[data-tooltip]:not([disabled]).has-tooltip-light::after { + border-color: rgba(245, 245, 245, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-light.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-light.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-light.has-tooltip-bottom::after { + border-color: transparent transparent rgba(245, 245, 245, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-light.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-light.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-light.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(245, 245, 245, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-light.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-light.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-light.has-tooltip-right::after { + border-color: transparent rgba(245, 245, 245, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-light:before, +[data-tooltip]:not(.is-disabled).has-tooltip-light:before, +[data-tooltip]:not([disabled]).has-tooltip-light:before { + background-color: rgba(245, 245, 245, 0.9); + color: rgba(0, 0, 0, 0.7); +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-dark::after, +[data-tooltip]:not(.is-disabled).has-tooltip-dark::after, +[data-tooltip]:not([disabled]).has-tooltip-dark::after { + border-color: rgba(54, 54, 54, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-dark.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-dark.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-dark.has-tooltip-bottom::after { + border-color: transparent transparent rgba(54, 54, 54, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-dark.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-dark.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-dark.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(54, 54, 54, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-dark.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-dark.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-dark.has-tooltip-right::after { + border-color: transparent rgba(54, 54, 54, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-dark:before, +[data-tooltip]:not(.is-disabled).has-tooltip-dark:before, +[data-tooltip]:not([disabled]).has-tooltip-dark:before { + background-color: rgba(54, 54, 54, 0.9); + color: #fff; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-primary::after, +[data-tooltip]:not(.is-disabled).has-tooltip-primary::after, +[data-tooltip]:not([disabled]).has-tooltip-primary::after { + border-color: rgba(0, 209, 178, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-primary.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-primary.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-primary.has-tooltip-bottom::after { + border-color: transparent transparent rgba(0, 209, 178, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-primary.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-primary.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-primary.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(0, 209, 178, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-primary.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-primary.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-primary.has-tooltip-right::after { + border-color: transparent rgba(0, 209, 178, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-primary:before, +[data-tooltip]:not(.is-disabled).has-tooltip-primary:before, +[data-tooltip]:not([disabled]).has-tooltip-primary:before { + background-color: rgba(0, 209, 178, 0.9); + color: #fff; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-link::after, +[data-tooltip]:not(.is-disabled).has-tooltip-link::after, +[data-tooltip]:not([disabled]).has-tooltip-link::after { + border-color: rgba(50, 115, 220, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-link.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-link.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-link.has-tooltip-bottom::after { + border-color: transparent transparent rgba(50, 115, 220, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-link.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-link.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-link.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(50, 115, 220, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-link.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-link.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-link.has-tooltip-right::after { + border-color: transparent rgba(50, 115, 220, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-link:before, +[data-tooltip]:not(.is-disabled).has-tooltip-link:before, +[data-tooltip]:not([disabled]).has-tooltip-link:before { + background-color: rgba(50, 115, 220, 0.9); + color: #fff; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-info::after, +[data-tooltip]:not(.is-disabled).has-tooltip-info::after, +[data-tooltip]:not([disabled]).has-tooltip-info::after { + border-color: rgba(50, 152, 220, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-info.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-info.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-info.has-tooltip-bottom::after { + border-color: transparent transparent rgba(50, 152, 220, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-info.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-info.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-info.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(50, 152, 220, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-info.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-info.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-info.has-tooltip-right::after { + border-color: transparent rgba(50, 152, 220, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-info:before, +[data-tooltip]:not(.is-disabled).has-tooltip-info:before, +[data-tooltip]:not([disabled]).has-tooltip-info:before { + background-color: rgba(50, 152, 220, 0.9); + color: #fff; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-success::after, +[data-tooltip]:not(.is-disabled).has-tooltip-success::after, +[data-tooltip]:not([disabled]).has-tooltip-success::after { + border-color: rgba(72, 199, 116, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-success.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-success.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-success.has-tooltip-bottom::after { + border-color: transparent transparent rgba(72, 199, 116, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-success.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-success.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-success.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(72, 199, 116, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-success.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-success.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-success.has-tooltip-right::after { + border-color: transparent rgba(72, 199, 116, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-success:before, +[data-tooltip]:not(.is-disabled).has-tooltip-success:before, +[data-tooltip]:not([disabled]).has-tooltip-success:before { + background-color: rgba(72, 199, 116, 0.9); + color: #fff; +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-warning::after, +[data-tooltip]:not(.is-disabled).has-tooltip-warning::after, +[data-tooltip]:not([disabled]).has-tooltip-warning::after { + border-color: rgba(255, 221, 87, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-warning.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-warning.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-warning.has-tooltip-bottom::after { + border-color: transparent transparent rgba(255, 221, 87, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-warning.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-warning.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-warning.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(255, 221, 87, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-warning.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-warning.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-warning.has-tooltip-right::after { + border-color: transparent rgba(255, 221, 87, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-warning:before, +[data-tooltip]:not(.is-disabled).has-tooltip-warning:before, +[data-tooltip]:not([disabled]).has-tooltip-warning:before { + background-color: rgba(255, 221, 87, 0.9); + color: rgba(0, 0, 0, 0.7); +} + +/* line 104, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-danger::after, +[data-tooltip]:not(.is-disabled).has-tooltip-danger::after, +[data-tooltip]:not([disabled]).has-tooltip-danger::after { + border-color: rgba(241, 70, 104, 0.9) transparent transparent transparent !important; +} + +/* line 107, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-danger.has-tooltip-bottom::after, +[data-tooltip]:not(.is-disabled).has-tooltip-danger.has-tooltip-bottom::after, +[data-tooltip]:not([disabled]).has-tooltip-danger.has-tooltip-bottom::after { + border-color: transparent transparent rgba(241, 70, 104, 0.9) transparent !important; +} + +/* line 110, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-danger.has-tooltip-left::after, +[data-tooltip]:not(.is-disabled).has-tooltip-danger.has-tooltip-left::after, +[data-tooltip]:not([disabled]).has-tooltip-danger.has-tooltip-left::after { + border-color: transparent transparent transparent rgba(241, 70, 104, 0.9) !important; +} + +/* line 113, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-danger.has-tooltip-right::after, +[data-tooltip]:not(.is-disabled).has-tooltip-danger.has-tooltip-right::after, +[data-tooltip]:not([disabled]).has-tooltip-danger.has-tooltip-right::after { + border-color: transparent rgba(241, 70, 104, 0.9) transparent transparent !important; +} + +/* line 115, src/sass/app.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-danger:before, +[data-tooltip]:not(.is-disabled).has-tooltip-danger:before, +[data-tooltip]:not([disabled]).has-tooltip-danger:before { + background-color: rgba(241, 70, 104, 0.9); + color: #fff; +} + +/* line 2, src/sass/_position.sass */ +[data-tooltip]:not(.is-loading):hover::before, +[data-tooltip]:not(.is-loading):hover::after, +[data-tooltip]:not(.is-loading).has-tooltip-active::before, +[data-tooltip]:not(.is-loading).has-tooltip-active::after, +[data-tooltip]:not(.is-disabled):hover::before, +[data-tooltip]:not(.is-disabled):hover::after, +[data-tooltip]:not(.is-disabled).has-tooltip-active::before, +[data-tooltip]:not(.is-disabled).has-tooltip-active::after, +[data-tooltip]:not([disabled]):hover::before, +[data-tooltip]:not([disabled]):hover::after, +[data-tooltip]:not([disabled]).has-tooltip-active::before, +[data-tooltip]:not([disabled]).has-tooltip-active::after { + opacity: 1; + visibility: visible; +} + +/* line 2, src/sass/_animation.sass */ +[data-tooltip]:not(.is-loading).has-tooltip-fade::before, +[data-tooltip]:not(.is-loading).has-tooltip-fade::after, +[data-tooltip]:not(.is-disabled).has-tooltip-fade::before, +[data-tooltip]:not(.is-disabled).has-tooltip-fade::after, +[data-tooltip]:not([disabled]).has-tooltip-fade::before, +[data-tooltip]:not([disabled]).has-tooltip-fade::after { + transition: opacity 0.3s linear, visibility 0.3s linear; +} + +@media screen and (max-width: 768px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-mobile.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-mobile.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-mobile.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-top-mobile::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (min-width: 769px), +print { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-tablet.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-tablet.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-tablet.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-top-tablet::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-tablet-only.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-top-tablet-only::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (max-width: 1023px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-touch.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-touch.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-touch.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-top-touch::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (min-width: 1024px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-desktop.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-desktop.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-desktop.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-top-desktop::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-desktop-only.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-top-desktop-only::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (max-width: 1215px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-until-widescreen.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-top-until-widescreen::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (min-width: 1216px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-widescreen.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-top-widescreen::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-widescreen-only.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-top-widescreen-only::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (max-width: 1407px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-until-fullhd.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-top-until-fullhd::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (min-width: 1408px) { + + /* line 10, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-top-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-top-fullhd.has-tooltip-arrow::after { + top: 0; + right: auto; + bottom: auto; + left: 50%; + margin-top: -5px; + margin-right: auto; + margin-bottom: auto; + margin-left: -5px; + border-color: rgba(74, 74, 74, 0.9) transparent transparent transparent; + } + + /* line 22, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-top-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-top-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-top-fullhd::before { + top: 0; + right: auto; + bottom: auto; + left: 50%; + top: 0; + margin-top: -5px; + margin-bottom: auto; + transform: translate(-50%, -100%); + } +} + +@media screen and (max-width: 768px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-mobile.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-mobile.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-mobile.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-right-mobile::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (min-width: 769px), +print { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-tablet.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-tablet.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-tablet.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-right-tablet::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-tablet-only.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-right-tablet-only::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (max-width: 1023px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-touch.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-touch.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-touch.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-right-touch::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (min-width: 1024px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-desktop.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-desktop.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-desktop.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-right-desktop::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-desktop-only.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-right-desktop-only::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (max-width: 1215px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-until-widescreen.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-right-until-widescreen::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (min-width: 1216px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-widescreen.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-right-widescreen::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-widescreen-only.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-right-widescreen-only::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (max-width: 1407px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-until-fullhd.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-right-until-fullhd::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (min-width: 1408px) { + + /* line 92, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-right-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-right-fullhd.has-tooltip-arrow::after { + top: auto; + right: 0; + bottom: 50%; + left: auto; + margin-top: auto; + margin-right: -6px; + margin-bottom: -6px; + margin-left: auto; + border-color: transparent rgba(74, 74, 74, 0.9) transparent transparent; + } + + /* line 104, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-right-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-right-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-right-fullhd::before { + top: auto; + right: -5px; + bottom: 50%; + left: auto; + margin-top: auto; + transform: translate(100%, 50%); + } +} + +@media screen and (max-width: 768px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-mobile.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-mobile.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-mobile.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-mobile::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (min-width: 769px), +print { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-tablet.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-tablet.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-tablet.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-tablet::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-tablet-only.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-tablet-only::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (max-width: 1023px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-touch.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-touch.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-touch.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-touch::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (min-width: 1024px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-desktop.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-desktop.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-desktop.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-desktop::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-desktop-only.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-desktop-only::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (max-width: 1215px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-until-widescreen.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-until-widescreen::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (min-width: 1216px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-widescreen.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-widescreen::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-widescreen-only.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-widescreen-only::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (max-width: 1407px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-until-fullhd.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-until-fullhd::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (min-width: 1408px) { + + /* line 38, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-bottom-fullhd.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: -1px; + left: 50%; + margin-top: auto; + margin-right: auto; + margin-bottom: -5px; + margin-left: -5px; + border-color: transparent transparent rgba(74, 74, 74, 0.9) transparent; + } + + /* line 50, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-bottom-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-bottom-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-bottom-fullhd::before { + top: auto; + right: auto; + bottom: 0; + left: 50%; + margin-top: auto; + margin-bottom: -5px; + transform: translate(-50%, 100%); + } +} + +@media screen and (max-width: 768px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-mobile.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-mobile.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-mobile.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-left-mobile::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (min-width: 769px), +print { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-tablet.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-tablet.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-tablet.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-left-tablet::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-tablet-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-tablet-only.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-left-tablet-only::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (max-width: 1023px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-touch.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-touch.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-touch.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-left-touch::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (min-width: 1024px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-desktop.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-desktop.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-desktop.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-left-desktop::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-desktop-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-desktop-only.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-left-desktop-only::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (max-width: 1215px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-until-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-until-widescreen.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-left-until-widescreen::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (min-width: 1216px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-widescreen.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-widescreen.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-left-widescreen::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-widescreen-only.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-widescreen-only.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-left-widescreen-only::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (max-width: 1407px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-until-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-until-fullhd.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-left-until-fullhd::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (min-width: 1408px) { + + /* line 66, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not(.is-disabled).has-tooltip-left-fullhd.has-tooltip-arrow::after, + [data-tooltip]:not([disabled]).has-tooltip-left-fullhd.has-tooltip-arrow::after { + top: auto; + right: auto; + bottom: 50%; + left: 0; + margin-top: auto; + margin-right: auto; + margin-bottom: -6px; + margin-left: -5px; + border-color: transparent transparent transparent rgba(74, 74, 74, 0.9); + } + + /* line 78, src/sass/_position.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-left-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-left-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-left-fullhd::before { + top: auto; + right: auto; + bottom: 50%; + left: -5px; + transform: translate(-100%, 50%); + } +} + +@media screen and (max-width: 768px) { + + /* line 39, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-mobile::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-mobile::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-mobile::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-mobile::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (min-width: 769px), +print { + + /* line 45, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-tablet::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-tablet::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-tablet::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-tablet::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 51, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-tablet-only::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-tablet-only::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-tablet-only::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-tablet-only::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (max-width: 1023px) { + + /* line 57, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-touch::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-touch::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-touch::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-touch::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (min-width: 1024px) { + + /* line 63, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-desktop::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-desktop::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-desktop::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-desktop::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 69, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-desktop-only::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-desktop-only::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-desktop-only::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-desktop-only::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (max-width: 1215px) { + + /* line 75, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-until-widescreen::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-until-widescreen::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-until-widescreen::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-until-widescreen::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (min-width: 1216px) { + + /* line 81, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-widescreen::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-widescreen::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-widescreen::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-widescreen::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 87, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-widescreen-only::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-widescreen-only::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-widescreen-only::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-widescreen-only::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (max-width: 1407px) { + + /* line 93, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-until-fullhd::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-until-fullhd::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-until-fullhd::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-until-fullhd::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (min-width: 1408px) { + + /* line 99, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-hidden-fullhd::after, + [data-tooltip]:not(.is-loading).has-tooltip-hidden-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-fullhd::after, + [data-tooltip]:not(.is-disabled).has-tooltip-hidden-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-hidden-fullhd::after, + [data-tooltip]:not([disabled]).has-tooltip-hidden-fullhd::before { + opacity: 0 !important; + display: none !important; + } +} + +@media screen and (max-width: 768px) { + + /* line 110, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-mobile::before { + text-align: left; + } +} + +@media screen and (min-width: 769px), +print { + + /* line 114, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-tablet::before { + text-align: left; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 118, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-tablet-only::before { + text-align: left; + } +} + +@media screen and (max-width: 1023px) { + + /* line 122, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-touch::before { + text-align: left; + } +} + +@media screen and (min-width: 1024px) { + + /* line 126, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-desktop::before { + text-align: left; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 130, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-desktop-only::before { + text-align: left; + } +} + +@media screen and (max-width: 1215px) { + + /* line 134, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-until-widescreen::before { + text-align: left; + } +} + +@media screen and (min-width: 1216px) { + + /* line 138, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-widescreen::before { + text-align: left; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 142, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-widescreen-only::before { + text-align: left; + } +} + +@media screen and (max-width: 1407px) { + + /* line 146, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-until-fullhd::before { + text-align: left; + } +} + +@media screen and (min-width: 1408px) { + + /* line 150, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-left-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-left-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-text-left-fullhd::before { + text-align: left; + } +} + +@media screen and (max-width: 768px) { + + /* line 110, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-mobile::before { + text-align: center; + } +} + +@media screen and (min-width: 769px), +print { + + /* line 114, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-tablet::before { + text-align: center; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 118, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-tablet-only::before { + text-align: center; + } +} + +@media screen and (max-width: 1023px) { + + /* line 122, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-touch::before { + text-align: center; + } +} + +@media screen and (min-width: 1024px) { + + /* line 126, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-desktop::before { + text-align: center; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 130, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-desktop-only::before { + text-align: center; + } +} + +@media screen and (max-width: 1215px) { + + /* line 134, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-until-widescreen::before { + text-align: center; + } +} + +@media screen and (min-width: 1216px) { + + /* line 138, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-widescreen::before { + text-align: center; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 142, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-widescreen-only::before { + text-align: center; + } +} + +@media screen and (max-width: 1407px) { + + /* line 146, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-until-fullhd::before { + text-align: center; + } +} + +@media screen and (min-width: 1408px) { + + /* line 150, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-centered-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-centered-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-text-centered-fullhd::before { + text-align: center; + } +} + +@media screen and (max-width: 768px) { + + /* line 110, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-mobile::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-mobile::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-mobile::before { + text-align: right; + } +} + +@media screen and (min-width: 769px), +print { + + /* line 114, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-tablet::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-tablet::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-tablet::before { + text-align: right; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + + /* line 118, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-tablet-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-tablet-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-tablet-only::before { + text-align: right; + } +} + +@media screen and (max-width: 1023px) { + + /* line 122, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-touch::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-touch::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-touch::before { + text-align: right; + } +} + +@media screen and (min-width: 1024px) { + + /* line 126, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-desktop::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-desktop::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-desktop::before { + text-align: right; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + + /* line 130, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-desktop-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-desktop-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-desktop-only::before { + text-align: right; + } +} + +@media screen and (max-width: 1215px) { + + /* line 134, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-until-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-until-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-until-widescreen::before { + text-align: right; + } +} + +@media screen and (min-width: 1216px) { + + /* line 138, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-widescreen::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-widescreen::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-widescreen::before { + text-align: right; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + + /* line 142, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-widescreen-only::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-widescreen-only::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-widescreen-only::before { + text-align: right; + } +} + +@media screen and (max-width: 1407px) { + + /* line 146, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-until-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-until-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-until-fullhd::before { + text-align: right; + } +} + +@media screen and (min-width: 1408px) { + + /* line 150, src/sass/_responsiveness.sass */ + [data-tooltip]:not(.is-loading).has-tooltip-text-right-fullhd::before, + [data-tooltip]:not(.is-disabled).has-tooltip-text-right-fullhd::before, + [data-tooltip]:not([disabled]).has-tooltip-text-right-fullhd::before { + text-align: right; + } +} + +/* line 129, src/sass/app.sass */ +span[data-tooltip] { + /* border-bottom: 1px dashed #dbdbdb; */ + border-bottom: 1px dotted #dbdbdb; + /* border-bottom: none; */ +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-white { + border-bottom-color: white; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-black { + border-bottom-color: #171717; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-light { + border-bottom-color: white; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-dark { + border-bottom-color: #424242; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-primary { + border-bottom-color: #00ebc7; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-link { + border-bottom-color: #4882e0; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-info { + border-bottom-color: #48a3e0; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-success { + border-bottom-color: #5bcd83; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-warning { + border-bottom-color: #ffe270; +} + +/* line 134, src/sass/app.sass */ +span[data-tooltip].has-tooltip-danger { + border-bottom-color: #f35e7c; +} + +/* line 139, src/sass/app.sass */ +.control span[data-tooltip] { + border-bottom: none; +} \ No newline at end of file diff --git a/fedcode/static/css/bulma.css b/fedcode/static/css/bulma.css new file mode 100644 index 0000000..9559ea4 --- /dev/null +++ b/fedcode/static/css/bulma.css @@ -0,0 +1,11331 @@ +/*! bulma.io v0.9.0 | MIT License | github.com/jgthms/bulma */ +@-webkit-keyframes spinAround { + from { + transform: rotate(0deg); + } + to { + transform: rotate(359deg); + } +} +@keyframes spinAround { + from { + transform: rotate(0deg); + } + to { + transform: rotate(359deg); + } +} + +.delete, .modal-close, .button, .file, .breadcrumb, .pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis, .tabs, .is-unselectable { + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.select:not(.is-multiple):not(.is-loading)::after, .navbar-link:not(.is-arrowless)::after { + border: 3px solid transparent; + border-radius: 2px; + border-right: 0; + border-top: 0; + content: " "; + display: block; + height: 0.625em; + margin-top: -0.4375em; + pointer-events: none; + position: absolute; + top: 50%; + transform: rotate(-45deg); + transform-origin: center; + width: 0.625em; +} + +.box:not(:last-child), .content:not(:last-child), .notification:not(:last-child), .progress:not(:last-child), .table:not(:last-child), .table-container:not(:last-child), .title:not(:last-child), +.subtitle:not(:last-child), .block:not(:last-child), .highlight:not(:last-child), .breadcrumb:not(:last-child), .level:not(:last-child), .message:not(:last-child), .pagination:not(:last-child), .tabs:not(:last-child) { + margin-bottom: 1.5rem; +} + +.delete, .modal-close { + -moz-appearance: none; + -webkit-appearance: none; + background-color: rgba(10, 10, 10, 0.2); + border: none; + border-radius: 290486px; + cursor: pointer; + pointer-events: auto; + display: inline-block; + flex-grow: 0; + flex-shrink: 0; + font-size: 0; + height: 20px; + max-height: 20px; + max-width: 20px; + min-height: 20px; + min-width: 20px; + outline: none; + position: relative; + vertical-align: top; + width: 20px; +} + +.delete::before, .modal-close::before, .delete::after, .modal-close::after { + background-color: white; + content: ""; + display: block; + left: 50%; + position: absolute; + top: 50%; + transform: translateX(-50%) translateY(-50%) rotate(45deg); + transform-origin: center center; +} + +.delete::before, .modal-close::before { + height: 2px; + width: 50%; +} + +.delete::after, .modal-close::after { + height: 50%; + width: 2px; +} + +.delete:hover, .modal-close:hover, .delete:focus, .modal-close:focus { + background-color: rgba(10, 10, 10, 0.3); +} + +.delete:active, .modal-close:active { + background-color: rgba(10, 10, 10, 0.4); +} + +.is-small.delete, .is-small.modal-close { + height: 16px; + max-height: 16px; + max-width: 16px; + min-height: 16px; + min-width: 16px; + width: 16px; +} + +.is-medium.delete, .is-medium.modal-close { + height: 24px; + max-height: 24px; + max-width: 24px; + min-height: 24px; + min-width: 24px; + width: 24px; +} + +.is-large.delete, .is-large.modal-close { + height: 32px; + max-height: 32px; + max-width: 32px; + min-height: 32px; + min-width: 32px; + width: 32px; +} + +.button.is-loading::after, .loader, .select.is-loading::after, .control.is-loading::after { + -webkit-animation: spinAround 500ms infinite linear; + animation: spinAround 500ms infinite linear; + border: 2px solid #dbdbdb; + border-radius: 290486px; + border-right-color: transparent; + border-top-color: transparent; + content: ""; + display: block; + height: 1em; + position: relative; + width: 1em; +} + +.image.is-square img, +.image.is-square .has-ratio, .image.is-1by1 img, +.image.is-1by1 .has-ratio, .image.is-5by4 img, +.image.is-5by4 .has-ratio, .image.is-4by3 img, +.image.is-4by3 .has-ratio, .image.is-3by2 img, +.image.is-3by2 .has-ratio, .image.is-5by3 img, +.image.is-5by3 .has-ratio, .image.is-16by9 img, +.image.is-16by9 .has-ratio, .image.is-2by1 img, +.image.is-2by1 .has-ratio, .image.is-3by1 img, +.image.is-3by1 .has-ratio, .image.is-4by5 img, +.image.is-4by5 .has-ratio, .image.is-3by4 img, +.image.is-3by4 .has-ratio, .image.is-2by3 img, +.image.is-2by3 .has-ratio, .image.is-3by5 img, +.image.is-3by5 .has-ratio, .image.is-9by16 img, +.image.is-9by16 .has-ratio, .image.is-1by2 img, +.image.is-1by2 .has-ratio, .image.is-1by3 img, +.image.is-1by3 .has-ratio, .modal, .modal-background, .is-overlay, .hero-video { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +.button, .input, .textarea, .select select, .file-cta, +.file-name, .pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis { + -moz-appearance: none; + -webkit-appearance: none; + align-items: center; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: none; + display: inline-flex; + font-size: 1rem; + height: 2.5em; + justify-content: flex-start; + line-height: 1.5; + padding-bottom: calc(0.5em - 1px); + padding-left: calc(0.75em - 1px); + padding-right: calc(0.75em - 1px); + padding-top: calc(0.5em - 1px); + position: relative; + vertical-align: top; +} + +.button:focus, .input:focus, .textarea:focus, .select select:focus, .file-cta:focus, +.file-name:focus, .pagination-previous:focus, +.pagination-next:focus, +.pagination-link:focus, +.pagination-ellipsis:focus, .is-focused.button, .is-focused.input, .is-focused.textarea, .select select.is-focused, .is-focused.file-cta, +.is-focused.file-name, .is-focused.pagination-previous, +.is-focused.pagination-next, +.is-focused.pagination-link, +.is-focused.pagination-ellipsis, .button:active, .input:active, .textarea:active, .select select:active, .file-cta:active, +.file-name:active, .pagination-previous:active, +.pagination-next:active, +.pagination-link:active, +.pagination-ellipsis:active, .is-active.button, .is-active.input, .is-active.textarea, .select select.is-active, .is-active.file-cta, +.is-active.file-name, .is-active.pagination-previous, +.is-active.pagination-next, +.is-active.pagination-link, +.is-active.pagination-ellipsis { + outline: none; +} + +.button[disabled], .input[disabled], .textarea[disabled], .select select[disabled], .file-cta[disabled], +.file-name[disabled], .pagination-previous[disabled], +.pagination-next[disabled], +.pagination-link[disabled], +.pagination-ellipsis[disabled], +fieldset[disabled] .button, +fieldset[disabled] .input, +fieldset[disabled] .textarea, +fieldset[disabled] .select select, +.select fieldset[disabled] select, +fieldset[disabled] .file-cta, +fieldset[disabled] .file-name, +fieldset[disabled] .pagination-previous, +fieldset[disabled] .pagination-next, +fieldset[disabled] .pagination-link, +fieldset[disabled] .pagination-ellipsis { + cursor: not-allowed; +} + +/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */ +html, +body, +p, +ol, +ul, +li, +dl, +dt, +dd, +blockquote, +figure, +fieldset, +legend, +textarea, +pre, +iframe, +hr, +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 0; + padding: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: 100%; + font-weight: normal; +} + +ul { + list-style: none; +} + +button, +input, +select, +textarea { + margin: 0; +} + +html { + box-sizing: border-box; +} + +*, *::before, *::after { + box-sizing: inherit; +} + +img, +video { + height: auto; + max-width: 100%; +} + +iframe { + border: 0; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +td:not([align]), +th:not([align]) { + text-align: inherit; +} + +html { + background-color: white; + font-size: 16px; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + min-width: 300px; + overflow-x: hidden; + overflow-y: scroll; + text-rendering: optimizeLegibility; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + text-size-adjust: 100%; +} + +article, +aside, +figure, +footer, +header, +hgroup, +section { + display: block; +} + +body, +button, +input, +select, +textarea { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif; +} + +code, +pre { + -moz-osx-font-smoothing: auto; + -webkit-font-smoothing: auto; + font-family: monospace; +} + +body { + color: #4a4a4a; + font-size: 1em; + font-weight: 400; + line-height: 1.5; +} + +a { + color: #3273dc; + cursor: pointer; + text-decoration: none; +} + +a strong { + color: currentColor; +} + +a:hover { + color: #363636; +} + +code { + background-color: whitesmoke; + color: #f14668; + font-size: 0.875em; + font-weight: normal; + padding: 0.25em 0.5em 0.25em; +} + +hr { + background-color: whitesmoke; + border: none; + display: block; + height: 2px; + margin: 1.5rem 0; +} + +img { + height: auto; + max-width: 100%; +} + +input[type="checkbox"], +input[type="radio"] { + vertical-align: baseline; +} + +small { + font-size: 0.875em; +} + +span { + font-style: inherit; + font-weight: inherit; +} + +strong { + color: #363636; + font-weight: 700; +} + +fieldset { + border: none; +} + +pre { + -webkit-overflow-scrolling: touch; + background-color: whitesmoke; + color: #4a4a4a; + font-size: 0.875em; + overflow-x: auto; + padding: 1.25rem 1.5rem; + white-space: pre; + word-wrap: normal; +} + +pre code { + background-color: transparent; + color: currentColor; + font-size: 1em; + padding: 0; +} + +table td, +table th { + vertical-align: top; +} + +table td:not([align]), +table th:not([align]) { + text-align: inherit; +} + +table th { + color: #363636; +} + +.box { + background-color: white; + border-radius: 6px; + box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02); + color: #4a4a4a; + display: block; + padding: 1.25rem; +} + +a.box:hover, a.box:focus { + box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0 0 1px #3273dc; +} + +a.box:active { + box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2), 0 0 0 1px #3273dc; +} + +.button { + background-color: white; + border-color: #dbdbdb; + border-width: 1px; + color: #363636; + cursor: pointer; + justify-content: center; + padding-bottom: calc(0.5em - 1px); + padding-left: 1em; + padding-right: 1em; + padding-top: calc(0.5em - 1px); + text-align: center; + white-space: nowrap; +} + +.button strong { + color: inherit; +} + +.button .icon, .button .icon.is-small, .button .icon.is-medium, .button .icon.is-large { + height: 1.5em; + width: 1.5em; +} + +.button .icon:first-child:not(:last-child) { + margin-left: calc(-0.5em - 1px); + margin-right: 0.25em; +} + +.button .icon:last-child:not(:first-child) { + margin-left: 0.25em; + margin-right: calc(-0.5em - 1px); +} + +.button .icon:first-child:last-child { + margin-left: calc(-0.5em - 1px); + margin-right: calc(-0.5em - 1px); +} + +.button:hover, .button.is-hovered { + border-color: #b5b5b5; + color: #363636; +} + +.button:focus, .button.is-focused { + border-color: #3273dc; + color: #363636; +} + +.button:focus:not(:active), .button.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.button:active, .button.is-active { + border-color: #4a4a4a; + color: #363636; +} + +.button.is-text { + background-color: transparent; + border-color: transparent; + color: #4a4a4a; + text-decoration: underline; +} + +.button.is-text:hover, .button.is-text.is-hovered, .button.is-text:focus, .button.is-text.is-focused { + background-color: whitesmoke; + color: #363636; +} + +.button.is-text:active, .button.is-text.is-active { + background-color: #e8e8e8; + color: #363636; +} + +.button.is-text[disabled], +fieldset[disabled] .button.is-text { + background-color: transparent; + border-color: transparent; + box-shadow: none; +} + +.button.is-white { + background-color: white; + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white:hover, .button.is-white.is-hovered { + background-color: #f9f9f9; + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white:focus, .button.is-white.is-focused { + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white:focus:not(:active), .button.is-white.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); +} + +.button.is-white:active, .button.is-white.is-active { + background-color: #f2f2f2; + border-color: transparent; + color: #0a0a0a; +} + +.button.is-white[disabled], +fieldset[disabled] .button.is-white { + background-color: white; + border-color: transparent; + box-shadow: none; +} + +.button.is-white.is-inverted { + background-color: #0a0a0a; + color: white; +} + +.button.is-white.is-inverted:hover, .button.is-white.is-inverted.is-hovered { + background-color: black; +} + +.button.is-white.is-inverted[disabled], +fieldset[disabled] .button.is-white.is-inverted { + background-color: #0a0a0a; + border-color: transparent; + box-shadow: none; + color: white; +} + +.button.is-white.is-loading::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-white.is-outlined { + background-color: transparent; + border-color: white; + color: white; +} + +.button.is-white.is-outlined:hover, .button.is-white.is-outlined.is-hovered, .button.is-white.is-outlined:focus, .button.is-white.is-outlined.is-focused { + background-color: white; + border-color: white; + color: #0a0a0a; +} + +.button.is-white.is-outlined.is-loading::after { + border-color: transparent transparent white white !important; +} + +.button.is-white.is-outlined.is-loading:hover::after, .button.is-white.is-outlined.is-loading.is-hovered::after, .button.is-white.is-outlined.is-loading:focus::after, .button.is-white.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-white.is-outlined[disabled], +fieldset[disabled] .button.is-white.is-outlined { + background-color: transparent; + border-color: white; + box-shadow: none; + color: white; +} + +.button.is-white.is-inverted.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + color: #0a0a0a; +} + +.button.is-white.is-inverted.is-outlined:hover, .button.is-white.is-inverted.is-outlined.is-hovered, .button.is-white.is-inverted.is-outlined:focus, .button.is-white.is-inverted.is-outlined.is-focused { + background-color: #0a0a0a; + color: white; +} + +.button.is-white.is-inverted.is-outlined.is-loading:hover::after, .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-white.is-inverted.is-outlined.is-loading:focus::after, .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent white white !important; +} + +.button.is-white.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-white.is-inverted.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + box-shadow: none; + color: #0a0a0a; +} + +.button.is-black { + background-color: #0a0a0a; + border-color: transparent; + color: white; +} + +.button.is-black:hover, .button.is-black.is-hovered { + background-color: #040404; + border-color: transparent; + color: white; +} + +.button.is-black:focus, .button.is-black.is-focused { + border-color: transparent; + color: white; +} + +.button.is-black:focus:not(:active), .button.is-black.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); +} + +.button.is-black:active, .button.is-black.is-active { + background-color: black; + border-color: transparent; + color: white; +} + +.button.is-black[disabled], +fieldset[disabled] .button.is-black { + background-color: #0a0a0a; + border-color: transparent; + box-shadow: none; +} + +.button.is-black.is-inverted { + background-color: white; + color: #0a0a0a; +} + +.button.is-black.is-inverted:hover, .button.is-black.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-black.is-inverted[disabled], +fieldset[disabled] .button.is-black.is-inverted { + background-color: white; + border-color: transparent; + box-shadow: none; + color: #0a0a0a; +} + +.button.is-black.is-loading::after { + border-color: transparent transparent white white !important; +} + +.button.is-black.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + color: #0a0a0a; +} + +.button.is-black.is-outlined:hover, .button.is-black.is-outlined.is-hovered, .button.is-black.is-outlined:focus, .button.is-black.is-outlined.is-focused { + background-color: #0a0a0a; + border-color: #0a0a0a; + color: white; +} + +.button.is-black.is-outlined.is-loading::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-black.is-outlined.is-loading:hover::after, .button.is-black.is-outlined.is-loading.is-hovered::after, .button.is-black.is-outlined.is-loading:focus::after, .button.is-black.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent white white !important; +} + +.button.is-black.is-outlined[disabled], +fieldset[disabled] .button.is-black.is-outlined { + background-color: transparent; + border-color: #0a0a0a; + box-shadow: none; + color: #0a0a0a; +} + +.button.is-black.is-inverted.is-outlined { + background-color: transparent; + border-color: white; + color: white; +} + +.button.is-black.is-inverted.is-outlined:hover, .button.is-black.is-inverted.is-outlined.is-hovered, .button.is-black.is-inverted.is-outlined:focus, .button.is-black.is-inverted.is-outlined.is-focused { + background-color: white; + color: #0a0a0a; +} + +.button.is-black.is-inverted.is-outlined.is-loading:hover::after, .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-black.is-inverted.is-outlined.is-loading:focus::after, .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #0a0a0a #0a0a0a !important; +} + +.button.is-black.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-black.is-inverted.is-outlined { + background-color: transparent; + border-color: white; + box-shadow: none; + color: white; +} + +.button.is-light { + background-color: whitesmoke; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-light:hover, .button.is-light.is-hovered { + background-color: #eeeeee; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-light:focus, .button.is-light.is-focused { + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-light:focus:not(:active), .button.is-light.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25); +} + +.button.is-light:active, .button.is-light.is-active { + background-color: #e8e8e8; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-light[disabled], +fieldset[disabled] .button.is-light { + background-color: whitesmoke; + border-color: transparent; + box-shadow: none; +} + +.button.is-light.is-inverted { + background-color: rgba(0, 0, 0, 0.7); + color: whitesmoke; +} + +.button.is-light.is-inverted:hover, .button.is-light.is-inverted.is-hovered { + background-color: rgba(0, 0, 0, 0.7); +} + +.button.is-light.is-inverted[disabled], +fieldset[disabled] .button.is-light.is-inverted { + background-color: rgba(0, 0, 0, 0.7); + border-color: transparent; + box-shadow: none; + color: whitesmoke; +} + +.button.is-light.is-loading::after { + border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important; +} + +.button.is-light.is-outlined { + background-color: transparent; + border-color: whitesmoke; + color: whitesmoke; +} + +.button.is-light.is-outlined:hover, .button.is-light.is-outlined.is-hovered, .button.is-light.is-outlined:focus, .button.is-light.is-outlined.is-focused { + background-color: whitesmoke; + border-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-light.is-outlined.is-loading::after { + border-color: transparent transparent whitesmoke whitesmoke !important; +} + +.button.is-light.is-outlined.is-loading:hover::after, .button.is-light.is-outlined.is-loading.is-hovered::after, .button.is-light.is-outlined.is-loading:focus::after, .button.is-light.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important; +} + +.button.is-light.is-outlined[disabled], +fieldset[disabled] .button.is-light.is-outlined { + background-color: transparent; + border-color: whitesmoke; + box-shadow: none; + color: whitesmoke; +} + +.button.is-light.is-inverted.is-outlined { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.7); + color: rgba(0, 0, 0, 0.7); +} + +.button.is-light.is-inverted.is-outlined:hover, .button.is-light.is-inverted.is-outlined.is-hovered, .button.is-light.is-inverted.is-outlined:focus, .button.is-light.is-inverted.is-outlined.is-focused { + background-color: rgba(0, 0, 0, 0.7); + color: whitesmoke; +} + +.button.is-light.is-inverted.is-outlined.is-loading:hover::after, .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-light.is-inverted.is-outlined.is-loading:focus::after, .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent whitesmoke whitesmoke !important; +} + +.button.is-light.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-light.is-inverted.is-outlined { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.7); + box-shadow: none; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-dark { + background-color: #363636; + border-color: transparent; + color: #fff; +} + +.button.is-dark:hover, .button.is-dark.is-hovered { + background-color: #2f2f2f; + border-color: transparent; + color: #fff; +} + +.button.is-dark:focus, .button.is-dark.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-dark:focus:not(:active), .button.is-dark.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25); +} + +.button.is-dark:active, .button.is-dark.is-active { + background-color: #292929; + border-color: transparent; + color: #fff; +} + +.button.is-dark[disabled], +fieldset[disabled] .button.is-dark { + background-color: #363636; + border-color: transparent; + box-shadow: none; +} + +.button.is-dark.is-inverted { + background-color: #fff; + color: #363636; +} + +.button.is-dark.is-inverted:hover, .button.is-dark.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-dark.is-inverted[disabled], +fieldset[disabled] .button.is-dark.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #363636; +} + +.button.is-dark.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-dark.is-outlined { + background-color: transparent; + border-color: #363636; + color: #363636; +} + +.button.is-dark.is-outlined:hover, .button.is-dark.is-outlined.is-hovered, .button.is-dark.is-outlined:focus, .button.is-dark.is-outlined.is-focused { + background-color: #363636; + border-color: #363636; + color: #fff; +} + +.button.is-dark.is-outlined.is-loading::after { + border-color: transparent transparent #363636 #363636 !important; +} + +.button.is-dark.is-outlined.is-loading:hover::after, .button.is-dark.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-outlined.is-loading:focus::after, .button.is-dark.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-dark.is-outlined[disabled], +fieldset[disabled] .button.is-dark.is-outlined { + background-color: transparent; + border-color: #363636; + box-shadow: none; + color: #363636; +} + +.button.is-dark.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-dark.is-inverted.is-outlined:hover, .button.is-dark.is-inverted.is-outlined.is-hovered, .button.is-dark.is-inverted.is-outlined:focus, .button.is-dark.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #363636; +} + +.button.is-dark.is-inverted.is-outlined.is-loading:hover::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-dark.is-inverted.is-outlined.is-loading:focus::after, .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #363636 #363636 !important; +} + +.button.is-dark.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-dark.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-primary { + background-color: #00d1b2; + border-color: transparent; + color: #fff; +} + +.button.is-primary:hover, .button.is-primary.is-hovered { + background-color: #00c4a7; + border-color: transparent; + color: #fff; +} + +.button.is-primary:focus, .button.is-primary.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-primary:focus:not(:active), .button.is-primary.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25); +} + +.button.is-primary:active, .button.is-primary.is-active { + background-color: #00b89c; + border-color: transparent; + color: #fff; +} + +.button.is-primary[disabled], +fieldset[disabled] .button.is-primary { + background-color: #00d1b2; + border-color: transparent; + box-shadow: none; +} + +.button.is-primary.is-inverted { + background-color: #fff; + color: #00d1b2; +} + +.button.is-primary.is-inverted:hover, .button.is-primary.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-primary.is-inverted[disabled], +fieldset[disabled] .button.is-primary.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #00d1b2; +} + +.button.is-primary.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-primary.is-outlined { + background-color: transparent; + border-color: #00d1b2; + color: #00d1b2; +} + +.button.is-primary.is-outlined:hover, .button.is-primary.is-outlined.is-hovered, .button.is-primary.is-outlined:focus, .button.is-primary.is-outlined.is-focused { + background-color: #00d1b2; + border-color: #00d1b2; + color: #fff; +} + +.button.is-primary.is-outlined.is-loading::after { + border-color: transparent transparent #00d1b2 #00d1b2 !important; +} + +.button.is-primary.is-outlined.is-loading:hover::after, .button.is-primary.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-outlined.is-loading:focus::after, .button.is-primary.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-primary.is-outlined[disabled], +fieldset[disabled] .button.is-primary.is-outlined { + background-color: transparent; + border-color: #00d1b2; + box-shadow: none; + color: #00d1b2; +} + +.button.is-primary.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-primary.is-inverted.is-outlined:hover, .button.is-primary.is-inverted.is-outlined.is-hovered, .button.is-primary.is-inverted.is-outlined:focus, .button.is-primary.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #00d1b2; +} + +.button.is-primary.is-inverted.is-outlined.is-loading:hover::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-primary.is-inverted.is-outlined.is-loading:focus::after, .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #00d1b2 #00d1b2 !important; +} + +.button.is-primary.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-primary.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-primary.is-light { + background-color: #ebfffc; + color: #00947e; +} + +.button.is-primary.is-light:hover, .button.is-primary.is-light.is-hovered { + background-color: #defffa; + border-color: transparent; + color: #00947e; +} + +.button.is-primary.is-light:active, .button.is-primary.is-light.is-active { + background-color: #d1fff8; + border-color: transparent; + color: #00947e; +} + +.button.is-link { + background-color: #3273dc; + border-color: transparent; + color: #fff; +} + +.button.is-link:hover, .button.is-link.is-hovered { + background-color: #276cda; + border-color: transparent; + color: #fff; +} + +.button.is-link:focus, .button.is-link.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-link:focus:not(:active), .button.is-link.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.button.is-link:active, .button.is-link.is-active { + background-color: #2366d1; + border-color: transparent; + color: #fff; +} + +.button.is-link[disabled], +fieldset[disabled] .button.is-link { + background-color: #3273dc; + border-color: transparent; + box-shadow: none; +} + +.button.is-link.is-inverted { + background-color: #fff; + color: #3273dc; +} + +.button.is-link.is-inverted:hover, .button.is-link.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-link.is-inverted[disabled], +fieldset[disabled] .button.is-link.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #3273dc; +} + +.button.is-link.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-link.is-outlined { + background-color: transparent; + border-color: #3273dc; + color: #3273dc; +} + +.button.is-link.is-outlined:hover, .button.is-link.is-outlined.is-hovered, .button.is-link.is-outlined:focus, .button.is-link.is-outlined.is-focused { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; +} + +.button.is-link.is-outlined.is-loading::after { + border-color: transparent transparent #3273dc #3273dc !important; +} + +.button.is-link.is-outlined.is-loading:hover::after, .button.is-link.is-outlined.is-loading.is-hovered::after, .button.is-link.is-outlined.is-loading:focus::after, .button.is-link.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-link.is-outlined[disabled], +fieldset[disabled] .button.is-link.is-outlined { + background-color: transparent; + border-color: #3273dc; + box-shadow: none; + color: #3273dc; +} + +.button.is-link.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-link.is-inverted.is-outlined:hover, .button.is-link.is-inverted.is-outlined.is-hovered, .button.is-link.is-inverted.is-outlined:focus, .button.is-link.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #3273dc; +} + +.button.is-link.is-inverted.is-outlined.is-loading:hover::after, .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-link.is-inverted.is-outlined.is-loading:focus::after, .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #3273dc #3273dc !important; +} + +.button.is-link.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-link.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-link.is-light { + background-color: #eef3fc; + color: #2160c4; +} + +.button.is-link.is-light:hover, .button.is-link.is-light.is-hovered { + background-color: #e3ecfa; + border-color: transparent; + color: #2160c4; +} + +.button.is-link.is-light:active, .button.is-link.is-light.is-active { + background-color: #d8e4f8; + border-color: transparent; + color: #2160c4; +} + +.button.is-info { + background-color: #3298dc; + border-color: transparent; + color: #fff; +} + +.button.is-info:hover, .button.is-info.is-hovered { + background-color: #2793da; + border-color: transparent; + color: #fff; +} + +.button.is-info:focus, .button.is-info.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-info:focus:not(:active), .button.is-info.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(50, 152, 220, 0.25); +} + +.button.is-info:active, .button.is-info.is-active { + background-color: #238cd1; + border-color: transparent; + color: #fff; +} + +.button.is-info[disabled], +fieldset[disabled] .button.is-info { + background-color: #3298dc; + border-color: transparent; + box-shadow: none; +} + +.button.is-info.is-inverted { + background-color: #fff; + color: #3298dc; +} + +.button.is-info.is-inverted:hover, .button.is-info.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-info.is-inverted[disabled], +fieldset[disabled] .button.is-info.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #3298dc; +} + +.button.is-info.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-info.is-outlined { + background-color: transparent; + border-color: #3298dc; + color: #3298dc; +} + +.button.is-info.is-outlined:hover, .button.is-info.is-outlined.is-hovered, .button.is-info.is-outlined:focus, .button.is-info.is-outlined.is-focused { + background-color: #3298dc; + border-color: #3298dc; + color: #fff; +} + +.button.is-info.is-outlined.is-loading::after { + border-color: transparent transparent #3298dc #3298dc !important; +} + +.button.is-info.is-outlined.is-loading:hover::after, .button.is-info.is-outlined.is-loading.is-hovered::after, .button.is-info.is-outlined.is-loading:focus::after, .button.is-info.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-info.is-outlined[disabled], +fieldset[disabled] .button.is-info.is-outlined { + background-color: transparent; + border-color: #3298dc; + box-shadow: none; + color: #3298dc; +} + +.button.is-info.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-info.is-inverted.is-outlined:hover, .button.is-info.is-inverted.is-outlined.is-hovered, .button.is-info.is-inverted.is-outlined:focus, .button.is-info.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #3298dc; +} + +.button.is-info.is-inverted.is-outlined.is-loading:hover::after, .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-info.is-inverted.is-outlined.is-loading:focus::after, .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #3298dc #3298dc !important; +} + +.button.is-info.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-info.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-info.is-light { + background-color: #eef6fc; + color: #1d72aa; +} + +.button.is-info.is-light:hover, .button.is-info.is-light.is-hovered { + background-color: #e3f1fa; + border-color: transparent; + color: #1d72aa; +} + +.button.is-info.is-light:active, .button.is-info.is-light.is-active { + background-color: #d8ebf8; + border-color: transparent; + color: #1d72aa; +} + +.button.is-success { + background-color: #48c774; + border-color: transparent; + color: #fff; +} + +.button.is-success:hover, .button.is-success.is-hovered { + background-color: #3ec46d; + border-color: transparent; + color: #fff; +} + +.button.is-success:focus, .button.is-success.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-success:focus:not(:active), .button.is-success.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(72, 199, 116, 0.25); +} + +.button.is-success:active, .button.is-success.is-active { + background-color: #3abb67; + border-color: transparent; + color: #fff; +} + +.button.is-success[disabled], +fieldset[disabled] .button.is-success { + background-color: #48c774; + border-color: transparent; + box-shadow: none; +} + +.button.is-success.is-inverted { + background-color: #fff; + color: #48c774; +} + +.button.is-success.is-inverted:hover, .button.is-success.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-success.is-inverted[disabled], +fieldset[disabled] .button.is-success.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #48c774; +} + +.button.is-success.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-success.is-outlined { + background-color: transparent; + border-color: #48c774; + color: #48c774; +} + +.button.is-success.is-outlined:hover, .button.is-success.is-outlined.is-hovered, .button.is-success.is-outlined:focus, .button.is-success.is-outlined.is-focused { + background-color: #48c774; + border-color: #48c774; + color: #fff; +} + +.button.is-success.is-outlined.is-loading::after { + border-color: transparent transparent #48c774 #48c774 !important; +} + +.button.is-success.is-outlined.is-loading:hover::after, .button.is-success.is-outlined.is-loading.is-hovered::after, .button.is-success.is-outlined.is-loading:focus::after, .button.is-success.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-success.is-outlined[disabled], +fieldset[disabled] .button.is-success.is-outlined { + background-color: transparent; + border-color: #48c774; + box-shadow: none; + color: #48c774; +} + +.button.is-success.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-success.is-inverted.is-outlined:hover, .button.is-success.is-inverted.is-outlined.is-hovered, .button.is-success.is-inverted.is-outlined:focus, .button.is-success.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #48c774; +} + +.button.is-success.is-inverted.is-outlined.is-loading:hover::after, .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-success.is-inverted.is-outlined.is-loading:focus::after, .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #48c774 #48c774 !important; +} + +.button.is-success.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-success.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-success.is-light { + background-color: #effaf3; + color: #257942; +} + +.button.is-success.is-light:hover, .button.is-success.is-light.is-hovered { + background-color: #e6f7ec; + border-color: transparent; + color: #257942; +} + +.button.is-success.is-light:active, .button.is-success.is-light.is-active { + background-color: #dcf4e4; + border-color: transparent; + color: #257942; +} + +.button.is-warning { + background-color: #ffdd57; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning:hover, .button.is-warning.is-hovered { + background-color: #ffdb4a; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning:focus, .button.is-warning.is-focused { + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning:focus:not(:active), .button.is-warning.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(255, 221, 87, 0.25); +} + +.button.is-warning:active, .button.is-warning.is-active { + background-color: #ffd83d; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning[disabled], +fieldset[disabled] .button.is-warning { + background-color: #ffdd57; + border-color: transparent; + box-shadow: none; +} + +.button.is-warning.is-inverted { + background-color: rgba(0, 0, 0, 0.7); + color: #ffdd57; +} + +.button.is-warning.is-inverted:hover, .button.is-warning.is-inverted.is-hovered { + background-color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning.is-inverted[disabled], +fieldset[disabled] .button.is-warning.is-inverted { + background-color: rgba(0, 0, 0, 0.7); + border-color: transparent; + box-shadow: none; + color: #ffdd57; +} + +.button.is-warning.is-loading::after { + border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important; +} + +.button.is-warning.is-outlined { + background-color: transparent; + border-color: #ffdd57; + color: #ffdd57; +} + +.button.is-warning.is-outlined:hover, .button.is-warning.is-outlined.is-hovered, .button.is-warning.is-outlined:focus, .button.is-warning.is-outlined.is-focused { + background-color: #ffdd57; + border-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning.is-outlined.is-loading::after { + border-color: transparent transparent #ffdd57 #ffdd57 !important; +} + +.button.is-warning.is-outlined.is-loading:hover::after, .button.is-warning.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-outlined.is-loading:focus::after, .button.is-warning.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent rgba(0, 0, 0, 0.7) rgba(0, 0, 0, 0.7) !important; +} + +.button.is-warning.is-outlined[disabled], +fieldset[disabled] .button.is-warning.is-outlined { + background-color: transparent; + border-color: #ffdd57; + box-shadow: none; + color: #ffdd57; +} + +.button.is-warning.is-inverted.is-outlined { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.7); + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning.is-inverted.is-outlined:hover, .button.is-warning.is-inverted.is-outlined.is-hovered, .button.is-warning.is-inverted.is-outlined:focus, .button.is-warning.is-inverted.is-outlined.is-focused { + background-color: rgba(0, 0, 0, 0.7); + color: #ffdd57; +} + +.button.is-warning.is-inverted.is-outlined.is-loading:hover::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-warning.is-inverted.is-outlined.is-loading:focus::after, .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #ffdd57 #ffdd57 !important; +} + +.button.is-warning.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-warning.is-inverted.is-outlined { + background-color: transparent; + border-color: rgba(0, 0, 0, 0.7); + box-shadow: none; + color: rgba(0, 0, 0, 0.7); +} + +.button.is-warning.is-light { + background-color: #fffbeb; + color: #947600; +} + +.button.is-warning.is-light:hover, .button.is-warning.is-light.is-hovered { + background-color: #fff8de; + border-color: transparent; + color: #947600; +} + +.button.is-warning.is-light:active, .button.is-warning.is-light.is-active { + background-color: #fff6d1; + border-color: transparent; + color: #947600; +} + +.button.is-danger { + background-color: #f14668; + border-color: transparent; + color: #fff; +} + +.button.is-danger:hover, .button.is-danger.is-hovered { + background-color: #f03a5f; + border-color: transparent; + color: #fff; +} + +.button.is-danger:focus, .button.is-danger.is-focused { + border-color: transparent; + color: #fff; +} + +.button.is-danger:focus:not(:active), .button.is-danger.is-focused:not(:active) { + box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25); +} + +.button.is-danger:active, .button.is-danger.is-active { + background-color: #ef2e55; + border-color: transparent; + color: #fff; +} + +.button.is-danger[disabled], +fieldset[disabled] .button.is-danger { + background-color: #f14668; + border-color: transparent; + box-shadow: none; +} + +.button.is-danger.is-inverted { + background-color: #fff; + color: #f14668; +} + +.button.is-danger.is-inverted:hover, .button.is-danger.is-inverted.is-hovered { + background-color: #f2f2f2; +} + +.button.is-danger.is-inverted[disabled], +fieldset[disabled] .button.is-danger.is-inverted { + background-color: #fff; + border-color: transparent; + box-shadow: none; + color: #f14668; +} + +.button.is-danger.is-loading::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-danger.is-outlined { + background-color: transparent; + border-color: #f14668; + color: #f14668; +} + +.button.is-danger.is-outlined:hover, .button.is-danger.is-outlined.is-hovered, .button.is-danger.is-outlined:focus, .button.is-danger.is-outlined.is-focused { + background-color: #f14668; + border-color: #f14668; + color: #fff; +} + +.button.is-danger.is-outlined.is-loading::after { + border-color: transparent transparent #f14668 #f14668 !important; +} + +.button.is-danger.is-outlined.is-loading:hover::after, .button.is-danger.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-outlined.is-loading:focus::after, .button.is-danger.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #fff #fff !important; +} + +.button.is-danger.is-outlined[disabled], +fieldset[disabled] .button.is-danger.is-outlined { + background-color: transparent; + border-color: #f14668; + box-shadow: none; + color: #f14668; +} + +.button.is-danger.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + color: #fff; +} + +.button.is-danger.is-inverted.is-outlined:hover, .button.is-danger.is-inverted.is-outlined.is-hovered, .button.is-danger.is-inverted.is-outlined:focus, .button.is-danger.is-inverted.is-outlined.is-focused { + background-color: #fff; + color: #f14668; +} + +.button.is-danger.is-inverted.is-outlined.is-loading:hover::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after, .button.is-danger.is-inverted.is-outlined.is-loading:focus::after, .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after { + border-color: transparent transparent #f14668 #f14668 !important; +} + +.button.is-danger.is-inverted.is-outlined[disabled], +fieldset[disabled] .button.is-danger.is-inverted.is-outlined { + background-color: transparent; + border-color: #fff; + box-shadow: none; + color: #fff; +} + +.button.is-danger.is-light { + background-color: #feecf0; + color: #cc0f35; +} + +.button.is-danger.is-light:hover, .button.is-danger.is-light.is-hovered { + background-color: #fde0e6; + border-color: transparent; + color: #cc0f35; +} + +.button.is-danger.is-light:active, .button.is-danger.is-light.is-active { + background-color: #fcd4dc; + border-color: transparent; + color: #cc0f35; +} + +.button.is-small { + border-radius: 2px; + font-size: 0.75rem; +} + +.button.is-normal { + font-size: 1rem; +} + +.button.is-medium { + font-size: 1.25rem; +} + +.button.is-large { + font-size: 1.5rem; +} + +.button[disabled], +fieldset[disabled] .button { + background-color: white; + border-color: #dbdbdb; + box-shadow: none; + opacity: 0.5; +} + +.button.is-fullwidth { + display: flex; + width: 100%; +} + +.button.is-loading { + color: transparent !important; + pointer-events: none; +} + +.button.is-loading::after { + position: absolute; + left: calc(50% - (1em / 2)); + top: calc(50% - (1em / 2)); + position: absolute !important; +} + +.button.is-static { + background-color: whitesmoke; + border-color: #dbdbdb; + color: #7a7a7a; + box-shadow: none; + pointer-events: none; +} + +.button.is-rounded { + border-radius: 290486px; + padding-left: calc(1em + 0.25em); + padding-right: calc(1em + 0.25em); +} + +.buttons { + align-items: center; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.buttons .button { + margin-bottom: 0.5rem; +} + +.buttons .button:not(:last-child):not(.is-fullwidth) { + margin-right: 0.5rem; +} + +.buttons:last-child { + margin-bottom: -0.5rem; +} + +.buttons:not(:last-child) { + margin-bottom: 1rem; +} + +.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large) { + border-radius: 2px; + font-size: 0.75rem; +} + +.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large) { + font-size: 1.25rem; +} + +.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium) { + font-size: 1.5rem; +} + +.buttons.has-addons .button:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.buttons.has-addons .button:not(:last-child) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + margin-right: -1px; +} + +.buttons.has-addons .button:last-child { + margin-right: 0; +} + +.buttons.has-addons .button:hover, .buttons.has-addons .button.is-hovered { + z-index: 2; +} + +.buttons.has-addons .button:focus, .buttons.has-addons .button.is-focused, .buttons.has-addons .button:active, .buttons.has-addons .button.is-active, .buttons.has-addons .button.is-selected { + z-index: 3; +} + +.buttons.has-addons .button:focus:hover, .buttons.has-addons .button.is-focused:hover, .buttons.has-addons .button:active:hover, .buttons.has-addons .button.is-active:hover, .buttons.has-addons .button.is-selected:hover { + z-index: 4; +} + +.buttons.has-addons .button.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.buttons.is-centered { + justify-content: center; +} + +.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth) { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +.buttons.is-right { + justify-content: flex-end; +} + +.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth) { + margin-left: 0.25rem; + margin-right: 0.25rem; +} + +.container { + flex-grow: 1; + margin: 0 auto; + position: relative; + width: auto; +} + +.container.is-fluid { + max-width: none; + padding-left: 32px; + padding-right: 32px; + width: 100%; +} + +@media screen and (min-width: 1024px) { + .container { + max-width: 960px; + } +} + +@media screen and (max-width: 1215px) { + .container.is-widescreen { + max-width: 1152px; + } +} + +@media screen and (max-width: 1407px) { + .container.is-fullhd { + max-width: 1344px; + } +} + +@media screen and (min-width: 1216px) { + .container { + max-width: 1152px; + } +} + +@media screen and (min-width: 1408px) { + .container { + max-width: 1344px; + } +} + +.content li + li { + margin-top: 0.25em; +} + +.content p:not(:last-child), +.content dl:not(:last-child), +.content ol:not(:last-child), +.content ul:not(:last-child), +.content blockquote:not(:last-child), +.content pre:not(:last-child), +.content table:not(:last-child) { + margin-bottom: 1em; +} + +.content h1, +.content h2, +.content h3, +.content h4, +.content h5, +.content h6 { + color: #363636; + font-weight: 600; + line-height: 1.125; +} + +.content h1 { + font-size: 2em; + margin-bottom: 0.5em; +} + +.content h1:not(:first-child) { + margin-top: 1em; +} + +.content h2 { + font-size: 1.75em; + margin-bottom: 0.5714em; +} + +.content h2:not(:first-child) { + margin-top: 1.1428em; +} + +.content h3 { + font-size: 1.5em; + margin-bottom: 0.6666em; +} + +.content h3:not(:first-child) { + margin-top: 1.3333em; +} + +.content h4 { + font-size: 1.25em; + margin-bottom: 0.8em; +} + +.content h5 { + font-size: 1.125em; + margin-bottom: 0.8888em; +} + +.content h6 { + font-size: 1em; + margin-bottom: 1em; +} + +.content blockquote { + background-color: whitesmoke; + border-left: 5px solid #dbdbdb; + padding: 1.25em 1.5em; +} + +.content ol { + list-style-position: outside; + margin-left: 2em; + margin-top: 1em; +} + +.content ol:not([type]) { + list-style-type: decimal; +} + +.content ol:not([type]).is-lower-alpha { + list-style-type: lower-alpha; +} + +.content ol:not([type]).is-lower-roman { + list-style-type: lower-roman; +} + +.content ol:not([type]).is-upper-alpha { + list-style-type: upper-alpha; +} + +.content ol:not([type]).is-upper-roman { + list-style-type: upper-roman; +} + +.content ul { + list-style: disc outside; + margin-left: 2em; + margin-top: 1em; +} + +.content ul ul { + list-style-type: circle; + margin-top: 0.5em; +} + +.content ul ul ul { + list-style-type: square; +} + +.content dd { + margin-left: 2em; +} + +.content figure { + margin-left: 2em; + margin-right: 2em; + text-align: center; +} + +.content figure:not(:first-child) { + margin-top: 2em; +} + +.content figure:not(:last-child) { + margin-bottom: 2em; +} + +.content figure img { + display: inline-block; +} + +.content figure figcaption { + font-style: italic; +} + +.content pre { + -webkit-overflow-scrolling: touch; + overflow-x: auto; + padding: 1.25em 1.5em; + white-space: pre; + word-wrap: normal; +} + +.content sup, +.content sub { + font-size: 75%; +} + +.content table { + width: 100%; +} + +.content table td, +.content table th { + border: 1px solid #dbdbdb; + border-width: 0 0 1px; + padding: 0.5em 0.75em; + vertical-align: top; +} + +.content table th { + color: #363636; +} + +.content table th:not([align]) { + text-align: inherit; +} + +.content table thead td, +.content table thead th { + border-width: 0 0 2px; + color: #363636; +} + +.content table tfoot td, +.content table tfoot th { + border-width: 2px 0 0; + color: #363636; +} + +.content table tbody tr:last-child td, +.content table tbody tr:last-child th { + border-bottom-width: 0; +} + +.content .tabs li + li { + margin-top: 0; +} + +.content.is-small { + font-size: 0.75rem; +} + +.content.is-medium { + font-size: 1.25rem; +} + +.content.is-large { + font-size: 1.5rem; +} + +.icon { + align-items: center; + display: inline-flex; + justify-content: center; + height: 1.5rem; + width: 1.5rem; +} + +.icon.is-small { + height: 1rem; + width: 1rem; +} + +.icon.is-medium { + height: 2rem; + width: 2rem; +} + +.icon.is-large { + height: 3rem; + width: 3rem; +} + +.image { + display: block; + position: relative; +} + +.image img { + display: block; + height: auto; + width: 100%; +} + +.image img.is-rounded { + border-radius: 290486px; +} + +.image.is-fullwidth { + width: 100%; +} + +.image.is-square img, +.image.is-square .has-ratio, .image.is-1by1 img, +.image.is-1by1 .has-ratio, .image.is-5by4 img, +.image.is-5by4 .has-ratio, .image.is-4by3 img, +.image.is-4by3 .has-ratio, .image.is-3by2 img, +.image.is-3by2 .has-ratio, .image.is-5by3 img, +.image.is-5by3 .has-ratio, .image.is-16by9 img, +.image.is-16by9 .has-ratio, .image.is-2by1 img, +.image.is-2by1 .has-ratio, .image.is-3by1 img, +.image.is-3by1 .has-ratio, .image.is-4by5 img, +.image.is-4by5 .has-ratio, .image.is-3by4 img, +.image.is-3by4 .has-ratio, .image.is-2by3 img, +.image.is-2by3 .has-ratio, .image.is-3by5 img, +.image.is-3by5 .has-ratio, .image.is-9by16 img, +.image.is-9by16 .has-ratio, .image.is-1by2 img, +.image.is-1by2 .has-ratio, .image.is-1by3 img, +.image.is-1by3 .has-ratio { + height: 100%; + width: 100%; +} + +.image.is-square, .image.is-1by1 { + padding-top: 100%; +} + +.image.is-5by4 { + padding-top: 80%; +} + +.image.is-4by3 { + padding-top: 75%; +} + +.image.is-3by2 { + padding-top: 66.6666%; +} + +.image.is-5by3 { + padding-top: 60%; +} + +.image.is-16by9 { + padding-top: 56.25%; +} + +.image.is-2by1 { + padding-top: 50%; +} + +.image.is-3by1 { + padding-top: 33.3333%; +} + +.image.is-4by5 { + padding-top: 125%; +} + +.image.is-3by4 { + padding-top: 133.3333%; +} + +.image.is-2by3 { + padding-top: 150%; +} + +.image.is-3by5 { + padding-top: 166.6666%; +} + +.image.is-9by16 { + padding-top: 177.7777%; +} + +.image.is-1by2 { + padding-top: 200%; +} + +.image.is-1by3 { + padding-top: 300%; +} + +.image.is-16x16 { + height: 16px; + width: 16px; +} + +.image.is-24x24 { + height: 24px; + width: 24px; +} + +.image.is-32x32 { + height: 32px; + width: 32px; +} + +.image.is-48x48 { + height: 48px; + width: 48px; +} + +.image.is-64x64 { + height: 64px; + width: 64px; +} + +.image.is-96x96 { + height: 96px; + width: 96px; +} + +.image.is-128x128 { + height: 128px; + width: 128px; +} + +.notification { + background-color: whitesmoke; + border-radius: 4px; + position: relative; + padding: 1.25rem 2.5rem 1.25rem 1.5rem; +} + +.notification a:not(.button):not(.dropdown-item) { + color: currentColor; + text-decoration: underline; +} + +.notification strong { + color: currentColor; +} + +.notification code, +.notification pre { + background: white; +} + +.notification pre code { + background: transparent; +} + +.notification > .delete { + right: 0.5rem; + position: absolute; + top: 0.5rem; +} + +.notification .title, +.notification .subtitle, +.notification .content { + color: currentColor; +} + +.notification.is-white { + background-color: white; + color: #0a0a0a; +} + +.notification.is-black { + background-color: #0a0a0a; + color: white; +} + +.notification.is-light { + background-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.notification.is-dark { + background-color: #363636; + color: #fff; +} + +.notification.is-primary { + background-color: #00d1b2; + color: #fff; +} + +.notification.is-primary.is-light { + background-color: #ebfffc; + color: #00947e; +} + +.notification.is-link { + background-color: #3273dc; + color: #fff; +} + +.notification.is-link.is-light { + background-color: #eef3fc; + color: #2160c4; +} + +.notification.is-info { + background-color: #3298dc; + color: #fff; +} + +.notification.is-info.is-light { + background-color: #eef6fc; + color: #1d72aa; +} + +.notification.is-success { + background-color: #48c774; + color: #fff; +} + +.notification.is-success.is-light { + background-color: #effaf3; + color: #257942; +} + +.notification.is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.notification.is-warning.is-light { + background-color: #fffbeb; + color: #947600; +} + +.notification.is-danger { + background-color: #f14668; + color: #fff; +} + +.notification.is-danger.is-light { + background-color: #feecf0; + color: #cc0f35; +} + +.progress { + -moz-appearance: none; + -webkit-appearance: none; + border: none; + border-radius: 290486px; + display: block; + height: 1rem; + overflow: hidden; + padding: 0; + width: 100%; +} + +.progress::-webkit-progress-bar { + background-color: #ededed; +} + +.progress::-webkit-progress-value { + background-color: #4a4a4a; +} + +.progress::-moz-progress-bar { + background-color: #4a4a4a; +} + +.progress::-ms-fill { + background-color: #4a4a4a; + border: none; +} + +.progress.is-white::-webkit-progress-value { + background-color: white; +} + +.progress.is-white::-moz-progress-bar { + background-color: white; +} + +.progress.is-white::-ms-fill { + background-color: white; +} + +.progress.is-white:indeterminate { + background-image: linear-gradient(to right, white 30%, #ededed 30%); +} + +.progress.is-black::-webkit-progress-value { + background-color: #0a0a0a; +} + +.progress.is-black::-moz-progress-bar { + background-color: #0a0a0a; +} + +.progress.is-black::-ms-fill { + background-color: #0a0a0a; +} + +.progress.is-black:indeterminate { + background-image: linear-gradient(to right, #0a0a0a 30%, #ededed 30%); +} + +.progress.is-light::-webkit-progress-value { + background-color: whitesmoke; +} + +.progress.is-light::-moz-progress-bar { + background-color: whitesmoke; +} + +.progress.is-light::-ms-fill { + background-color: whitesmoke; +} + +.progress.is-light:indeterminate { + background-image: linear-gradient(to right, whitesmoke 30%, #ededed 30%); +} + +.progress.is-dark::-webkit-progress-value { + background-color: #363636; +} + +.progress.is-dark::-moz-progress-bar { + background-color: #363636; +} + +.progress.is-dark::-ms-fill { + background-color: #363636; +} + +.progress.is-dark:indeterminate { + background-image: linear-gradient(to right, #363636 30%, #ededed 30%); +} + +.progress.is-primary::-webkit-progress-value { + background-color: #00d1b2; +} + +.progress.is-primary::-moz-progress-bar { + background-color: #00d1b2; +} + +.progress.is-primary::-ms-fill { + background-color: #00d1b2; +} + +.progress.is-primary:indeterminate { + background-image: linear-gradient(to right, #00d1b2 30%, #ededed 30%); +} + +.progress.is-link::-webkit-progress-value { + background-color: #3273dc; +} + +.progress.is-link::-moz-progress-bar { + background-color: #3273dc; +} + +.progress.is-link::-ms-fill { + background-color: #3273dc; +} + +.progress.is-link:indeterminate { + background-image: linear-gradient(to right, #3273dc 30%, #ededed 30%); +} + +.progress.is-info::-webkit-progress-value { + background-color: #3298dc; +} + +.progress.is-info::-moz-progress-bar { + background-color: #3298dc; +} + +.progress.is-info::-ms-fill { + background-color: #3298dc; +} + +.progress.is-info:indeterminate { + background-image: linear-gradient(to right, #3298dc 30%, #ededed 30%); +} + +.progress.is-success::-webkit-progress-value { + background-color: #48c774; +} + +.progress.is-success::-moz-progress-bar { + background-color: #48c774; +} + +.progress.is-success::-ms-fill { + background-color: #48c774; +} + +.progress.is-success:indeterminate { + background-image: linear-gradient(to right, #48c774 30%, #ededed 30%); +} + +.progress.is-warning::-webkit-progress-value { + background-color: #ffdd57; +} + +.progress.is-warning::-moz-progress-bar { + background-color: #ffdd57; +} + +.progress.is-warning::-ms-fill { + background-color: #ffdd57; +} + +.progress.is-warning:indeterminate { + background-image: linear-gradient(to right, #ffdd57 30%, #ededed 30%); +} + +.progress.is-danger::-webkit-progress-value { + background-color: #f14668; +} + +.progress.is-danger::-moz-progress-bar { + background-color: #f14668; +} + +.progress.is-danger::-ms-fill { + background-color: #f14668; +} + +.progress.is-danger:indeterminate { + background-image: linear-gradient(to right, #f14668 30%, #ededed 30%); +} + +.progress:indeterminate { + -webkit-animation-duration: 1.5s; + animation-duration: 1.5s; + -webkit-animation-iteration-count: infinite; + animation-iteration-count: infinite; + -webkit-animation-name: moveIndeterminate; + animation-name: moveIndeterminate; + -webkit-animation-timing-function: linear; + animation-timing-function: linear; + background-color: #ededed; + background-image: linear-gradient(to right, #4a4a4a 30%, #ededed 30%); + background-position: top left; + background-repeat: no-repeat; + background-size: 150% 150%; +} + +.progress:indeterminate::-webkit-progress-bar { + background-color: transparent; +} + +.progress:indeterminate::-moz-progress-bar { + background-color: transparent; +} + +.progress.is-small { + height: 0.75rem; +} + +.progress.is-medium { + height: 1.25rem; +} + +.progress.is-large { + height: 1.5rem; +} + +@-webkit-keyframes moveIndeterminate { + from { + background-position: 200% 0; + } + to { + background-position: -200% 0; + } +} + +@keyframes moveIndeterminate { + from { + background-position: 200% 0; + } + to { + background-position: -200% 0; + } +} + +.table { + background-color: white; + color: #363636; +} + +.table td, +.table th { + border: 1px solid #dbdbdb; + border-width: 0 0 1px; + padding: 0.5em 0.75em; + vertical-align: top; +} + +.table td.is-white, +.table th.is-white { + background-color: white; + border-color: white; + color: #0a0a0a; +} + +.table td.is-black, +.table th.is-black { + background-color: #0a0a0a; + border-color: #0a0a0a; + color: white; +} + +.table td.is-light, +.table th.is-light { + background-color: whitesmoke; + border-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.table td.is-dark, +.table th.is-dark { + background-color: #363636; + border-color: #363636; + color: #fff; +} + +.table td.is-primary, +.table th.is-primary { + background-color: #00d1b2; + border-color: #00d1b2; + color: #fff; +} + +.table td.is-link, +.table th.is-link { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; +} + +.table td.is-info, +.table th.is-info { + background-color: #3298dc; + border-color: #3298dc; + color: #fff; +} + +.table td.is-success, +.table th.is-success { + background-color: #48c774; + border-color: #48c774; + color: #fff; +} + +.table td.is-warning, +.table th.is-warning { + background-color: #ffdd57; + border-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.table td.is-danger, +.table th.is-danger { + background-color: #f14668; + border-color: #f14668; + color: #fff; +} + +.table td.is-narrow, +.table th.is-narrow { + white-space: nowrap; + width: 1%; +} + +.table td.is-selected, +.table th.is-selected { + background-color: #00d1b2; + color: #fff; +} + +.table td.is-selected a, +.table td.is-selected strong, +.table th.is-selected a, +.table th.is-selected strong { + color: currentColor; +} + +.table td.is-vcentered, +.table th.is-vcentered { + vertical-align: middle; +} + +.table th { + color: #363636; +} + +.table th:not([align]) { + text-align: inherit; +} + +.table tr.is-selected { + background-color: #00d1b2; + color: #fff; +} + +.table tr.is-selected a, +.table tr.is-selected strong { + color: currentColor; +} + +.table tr.is-selected td, +.table tr.is-selected th { + border-color: #fff; + color: currentColor; +} + +.table thead { + background-color: transparent; +} + +.table thead td, +.table thead th { + border-width: 0 0 2px; + color: #363636; +} + +.table tfoot { + background-color: transparent; +} + +.table tfoot td, +.table tfoot th { + border-width: 2px 0 0; + color: #363636; +} + +.table tbody { + background-color: transparent; +} + +.table tbody tr:last-child td, +.table tbody tr:last-child th { + border-bottom-width: 0; +} + +.table.is-bordered td, +.table.is-bordered th { + border-width: 1px; +} + +.table.is-bordered tr:last-child td, +.table.is-bordered tr:last-child th { + border-bottom-width: 1px; +} + +.table.is-fullwidth { + width: 100%; +} + +.table.is-hoverable tbody tr:not(.is-selected):hover { + background-color: #fafafa; +} + +.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover { + background-color: #fafafa; +} + +.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even) { + background-color: whitesmoke; +} + +.table.is-narrow td, +.table.is-narrow th { + padding: 0.25em 0.5em; +} + +.table.is-striped tbody tr:not(.is-selected):nth-child(even) { + background-color: #fafafa; +} + +.table-container { + -webkit-overflow-scrolling: touch; + overflow: auto; + overflow-y: hidden; + max-width: 100%; +} + +.tags { + align-items: center; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.tags .tag { + margin-bottom: 0.5rem; +} + +.tags .tag:not(:last-child) { + margin-right: 0.5rem; +} + +.tags:last-child { + margin-bottom: -0.5rem; +} + +.tags:not(:last-child) { + margin-bottom: 1rem; +} + +.tags.are-medium .tag:not(.is-normal):not(.is-large) { + font-size: 1rem; +} + +.tags.are-large .tag:not(.is-normal):not(.is-medium) { + font-size: 1.25rem; +} + +.tags.is-centered { + justify-content: center; +} + +.tags.is-centered .tag { + margin-right: 0.25rem; + margin-left: 0.25rem; +} + +.tags.is-right { + justify-content: flex-end; +} + +.tags.is-right .tag:not(:first-child) { + margin-left: 0.5rem; +} + +.tags.is-right .tag:not(:last-child) { + margin-right: 0; +} + +.tags.has-addons .tag { + margin-right: 0; +} + +.tags.has-addons .tag:not(:first-child) { + margin-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.tags.has-addons .tag:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.tag:not(body) { + align-items: center; + background-color: whitesmoke; + border-radius: 4px; + color: #4a4a4a; + display: inline-flex; + font-size: 0.75rem; + height: 2em; + justify-content: center; + line-height: 1.5; + padding-left: 0.75em; + padding-right: 0.75em; + white-space: nowrap; +} + +.tag:not(body) .delete { + margin-left: 0.25rem; + margin-right: -0.375rem; +} + +.tag:not(body).is-white { + background-color: white; + color: #0a0a0a; +} + +.tag:not(body).is-black { + background-color: #0a0a0a; + color: white; +} + +.tag:not(body).is-light { + background-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.tag:not(body).is-dark { + background-color: #363636; + color: #fff; +} + +.tag:not(body).is-primary { + background-color: #00d1b2; + color: #fff; +} + +.tag:not(body).is-primary.is-light { + background-color: #ebfffc; + color: #00947e; +} + +.tag:not(body).is-link { + background-color: #3273dc; + color: #fff; +} + +.tag:not(body).is-link.is-light { + background-color: #eef3fc; + color: #2160c4; +} + +.tag:not(body).is-info { + background-color: #3298dc; + color: #fff; +} + +.tag:not(body).is-info.is-light { + background-color: #eef6fc; + color: #1d72aa; +} + +.tag:not(body).is-success { + background-color: #48c774; + color: #fff; +} + +.tag:not(body).is-success.is-light { + background-color: #effaf3; + color: #257942; +} + +.tag:not(body).is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.tag:not(body).is-warning.is-light { + background-color: #fffbeb; + color: #947600; +} + +.tag:not(body).is-danger { + background-color: #f14668; + color: #fff; +} + +.tag:not(body).is-danger.is-light { + background-color: #feecf0; + color: #cc0f35; +} + +.tag:not(body).is-normal { + font-size: 0.75rem; +} + +.tag:not(body).is-medium { + font-size: 1rem; +} + +.tag:not(body).is-large { + font-size: 1.25rem; +} + +.tag:not(body) .icon:first-child:not(:last-child) { + margin-left: -0.375em; + margin-right: 0.1875em; +} + +.tag:not(body) .icon:last-child:not(:first-child) { + margin-left: 0.1875em; + margin-right: -0.375em; +} + +.tag:not(body) .icon:first-child:last-child { + margin-left: -0.375em; + margin-right: -0.375em; +} + +.tag:not(body).is-delete { + margin-left: 1px; + padding: 0; + position: relative; + width: 2em; +} + +.tag:not(body).is-delete::before, .tag:not(body).is-delete::after { + background-color: currentColor; + content: ""; + display: block; + left: 50%; + position: absolute; + top: 50%; + transform: translateX(-50%) translateY(-50%) rotate(45deg); + transform-origin: center center; +} + +.tag:not(body).is-delete::before { + height: 1px; + width: 50%; +} + +.tag:not(body).is-delete::after { + height: 50%; + width: 1px; +} + +.tag:not(body).is-delete:hover, .tag:not(body).is-delete:focus { + background-color: #e8e8e8; +} + +.tag:not(body).is-delete:active { + background-color: #dbdbdb; +} + +.tag:not(body).is-rounded { + border-radius: 290486px; +} + +a.tag:hover { + text-decoration: underline; +} + +.title, +.subtitle { + word-break: break-word; +} + +.title em, +.title span, +.subtitle em, +.subtitle span { + font-weight: inherit; +} + +.title sub, +.subtitle sub { + font-size: 0.75em; +} + +.title sup, +.subtitle sup { + font-size: 0.75em; +} + +.title .tag, +.subtitle .tag { + vertical-align: middle; +} + +.title { + color: #363636; + font-size: 2rem; + font-weight: 600; + line-height: 1.125; +} + +.title strong { + color: inherit; + font-weight: inherit; +} + +.title + .highlight { + margin-top: -0.75rem; +} + +.title:not(.is-spaced) + .subtitle { + margin-top: -1.25rem; +} + +.title.is-1 { + font-size: 3rem; +} + +.title.is-2 { + font-size: 2.5rem; +} + +.title.is-3 { + font-size: 2rem; +} + +.title.is-4 { + font-size: 1.5rem; +} + +.title.is-5 { + font-size: 1.25rem; +} + +.title.is-6 { + font-size: 1rem; +} + +.title.is-7 { + font-size: 0.75rem; +} + +.subtitle { + color: #4a4a4a; + font-size: 1.25rem; + font-weight: 400; + line-height: 1.25; +} + +.subtitle strong { + color: #363636; + font-weight: 600; +} + +.subtitle:not(.is-spaced) + .title { + margin-top: -1.25rem; +} + +.subtitle.is-1 { + font-size: 3rem; +} + +.subtitle.is-2 { + font-size: 2.5rem; +} + +.subtitle.is-3 { + font-size: 2rem; +} + +.subtitle.is-4 { + font-size: 1.5rem; +} + +.subtitle.is-5 { + font-size: 1.25rem; +} + +.subtitle.is-6 { + font-size: 1rem; +} + +.subtitle.is-7 { + font-size: 0.75rem; +} + +.heading { + display: block; + font-size: 11px; + letter-spacing: 1px; + margin-bottom: 5px; + text-transform: uppercase; +} + +.highlight { + font-weight: 400; + max-width: 100%; + overflow: hidden; + padding: 0; +} + +.highlight pre { + overflow: auto; + max-width: 100%; +} + +.number { + align-items: center; + background-color: whitesmoke; + border-radius: 290486px; + display: inline-flex; + font-size: 1.25rem; + height: 2em; + justify-content: center; + margin-right: 1.5rem; + min-width: 2.5em; + padding: 0.25rem 0.5rem; + text-align: center; + vertical-align: top; +} + +.input, .textarea, .select select { + background-color: white; + border-color: #dbdbdb; + border-radius: 4px; + color: #363636; +} + +.input::-moz-placeholder, .textarea::-moz-placeholder, .select select::-moz-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input::-webkit-input-placeholder, .textarea::-webkit-input-placeholder, .select select::-webkit-input-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input:-moz-placeholder, .textarea:-moz-placeholder, .select select:-moz-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input:-ms-input-placeholder, .textarea:-ms-input-placeholder, .select select:-ms-input-placeholder { + color: rgba(54, 54, 54, 0.3); +} + +.input:hover, .textarea:hover, .select select:hover, .is-hovered.input, .is-hovered.textarea, .select select.is-hovered { + border-color: #b5b5b5; +} + +.input:focus, .textarea:focus, .select select:focus, .is-focused.input, .is-focused.textarea, .select select.is-focused, .input:active, .textarea:active, .select select:active, .is-active.input, .is-active.textarea, .select select.is-active { + border-color: #3273dc; + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.input[disabled], .textarea[disabled], .select select[disabled], +fieldset[disabled] .input, +fieldset[disabled] .textarea, +fieldset[disabled] .select select, +.select fieldset[disabled] select { + background-color: whitesmoke; + border-color: whitesmoke; + box-shadow: none; + color: #7a7a7a; +} + +.input[disabled]::-moz-placeholder, .textarea[disabled]::-moz-placeholder, .select select[disabled]::-moz-placeholder, +fieldset[disabled] .input::-moz-placeholder, +fieldset[disabled] .textarea::-moz-placeholder, +fieldset[disabled] .select select::-moz-placeholder, +.select fieldset[disabled] select::-moz-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input[disabled]::-webkit-input-placeholder, .textarea[disabled]::-webkit-input-placeholder, .select select[disabled]::-webkit-input-placeholder, +fieldset[disabled] .input::-webkit-input-placeholder, +fieldset[disabled] .textarea::-webkit-input-placeholder, +fieldset[disabled] .select select::-webkit-input-placeholder, +.select fieldset[disabled] select::-webkit-input-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input[disabled]:-moz-placeholder, .textarea[disabled]:-moz-placeholder, .select select[disabled]:-moz-placeholder, +fieldset[disabled] .input:-moz-placeholder, +fieldset[disabled] .textarea:-moz-placeholder, +fieldset[disabled] .select select:-moz-placeholder, +.select fieldset[disabled] select:-moz-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input[disabled]:-ms-input-placeholder, .textarea[disabled]:-ms-input-placeholder, .select select[disabled]:-ms-input-placeholder, +fieldset[disabled] .input:-ms-input-placeholder, +fieldset[disabled] .textarea:-ms-input-placeholder, +fieldset[disabled] .select select:-ms-input-placeholder, +.select fieldset[disabled] select:-ms-input-placeholder { + color: rgba(122, 122, 122, 0.3); +} + +.input, .textarea { + box-shadow: inset 0 0.0625em 0.125em rgba(10, 10, 10, 0.05); + max-width: 100%; + width: 100%; +} + +.input[readonly], .textarea[readonly] { + box-shadow: none; +} + +.is-white.input, .is-white.textarea { + border-color: white; +} + +.is-white.input:focus, .is-white.textarea:focus, .is-white.is-focused.input, .is-white.is-focused.textarea, .is-white.input:active, .is-white.textarea:active, .is-white.is-active.input, .is-white.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); +} + +.is-black.input, .is-black.textarea { + border-color: #0a0a0a; +} + +.is-black.input:focus, .is-black.textarea:focus, .is-black.is-focused.input, .is-black.is-focused.textarea, .is-black.input:active, .is-black.textarea:active, .is-black.is-active.input, .is-black.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); +} + +.is-light.input, .is-light.textarea { + border-color: whitesmoke; +} + +.is-light.input:focus, .is-light.textarea:focus, .is-light.is-focused.input, .is-light.is-focused.textarea, .is-light.input:active, .is-light.textarea:active, .is-light.is-active.input, .is-light.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25); +} + +.is-dark.input, .is-dark.textarea { + border-color: #363636; +} + +.is-dark.input:focus, .is-dark.textarea:focus, .is-dark.is-focused.input, .is-dark.is-focused.textarea, .is-dark.input:active, .is-dark.textarea:active, .is-dark.is-active.input, .is-dark.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25); +} + +.is-primary.input, .is-primary.textarea { + border-color: #00d1b2; +} + +.is-primary.input:focus, .is-primary.textarea:focus, .is-primary.is-focused.input, .is-primary.is-focused.textarea, .is-primary.input:active, .is-primary.textarea:active, .is-primary.is-active.input, .is-primary.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25); +} + +.is-link.input, .is-link.textarea { + border-color: #3273dc; +} + +.is-link.input:focus, .is-link.textarea:focus, .is-link.is-focused.input, .is-link.is-focused.textarea, .is-link.input:active, .is-link.textarea:active, .is-link.is-active.input, .is-link.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.is-info.input, .is-info.textarea { + border-color: #3298dc; +} + +.is-info.input:focus, .is-info.textarea:focus, .is-info.is-focused.input, .is-info.is-focused.textarea, .is-info.input:active, .is-info.textarea:active, .is-info.is-active.input, .is-info.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(50, 152, 220, 0.25); +} + +.is-success.input, .is-success.textarea { + border-color: #48c774; +} + +.is-success.input:focus, .is-success.textarea:focus, .is-success.is-focused.input, .is-success.is-focused.textarea, .is-success.input:active, .is-success.textarea:active, .is-success.is-active.input, .is-success.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(72, 199, 116, 0.25); +} + +.is-warning.input, .is-warning.textarea { + border-color: #ffdd57; +} + +.is-warning.input:focus, .is-warning.textarea:focus, .is-warning.is-focused.input, .is-warning.is-focused.textarea, .is-warning.input:active, .is-warning.textarea:active, .is-warning.is-active.input, .is-warning.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(255, 221, 87, 0.25); +} + +.is-danger.input, .is-danger.textarea { + border-color: #f14668; +} + +.is-danger.input:focus, .is-danger.textarea:focus, .is-danger.is-focused.input, .is-danger.is-focused.textarea, .is-danger.input:active, .is-danger.textarea:active, .is-danger.is-active.input, .is-danger.is-active.textarea { + box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25); +} + +.is-small.input, .is-small.textarea { + border-radius: 2px; + font-size: 0.75rem; +} + +.is-medium.input, .is-medium.textarea { + font-size: 1.25rem; +} + +.is-large.input, .is-large.textarea { + font-size: 1.5rem; +} + +.is-fullwidth.input, .is-fullwidth.textarea { + display: block; + width: 100%; +} + +.is-inline.input, .is-inline.textarea { + display: inline; + width: auto; +} + +.input.is-rounded { + border-radius: 290486px; + padding-left: calc(calc(0.75em - 1px) + 0.375em); + padding-right: calc(calc(0.75em - 1px) + 0.375em); +} + +.input.is-static { + background-color: transparent; + border-color: transparent; + box-shadow: none; + padding-left: 0; + padding-right: 0; +} + +.textarea { + display: block; + max-width: 100%; + min-width: 100%; + padding: calc(0.75em - 1px); + resize: vertical; +} + +.textarea:not([rows]) { + max-height: 40em; + min-height: 8em; +} + +.textarea[rows] { + height: initial; +} + +.textarea.has-fixed-size { + resize: none; +} + +.checkbox, .radio { + cursor: pointer; + display: inline-block; + line-height: 1.25; + position: relative; +} + +.checkbox input, .radio input { + cursor: pointer; +} + +.checkbox:hover, .radio:hover { + color: #363636; +} + +.checkbox[disabled], .radio[disabled], +fieldset[disabled] .checkbox, +fieldset[disabled] .radio { + color: #7a7a7a; + cursor: not-allowed; +} + +.radio + .radio { + margin-left: 0.5em; +} + +.select { + display: inline-block; + max-width: 100%; + position: relative; + vertical-align: top; +} + +.select:not(.is-multiple) { + height: 2.5em; +} + +.select:not(.is-multiple):not(.is-loading)::after { + border-color: #3273dc; + right: 1.125em; + z-index: 4; +} + +.select.is-rounded select { + border-radius: 290486px; + padding-left: 1em; +} + +.select select { + cursor: pointer; + display: block; + font-size: 1em; + max-width: 100%; + outline: none; +} + +.select select::-ms-expand { + display: none; +} + +.select select[disabled]:hover, +fieldset[disabled] .select select:hover { + border-color: whitesmoke; +} + +.select select:not([multiple]) { + padding-right: 2.5em; +} + +.select select[multiple] { + height: auto; + padding: 0; +} + +.select select[multiple] option { + padding: 0.5em 1em; +} + +.select:not(.is-multiple):not(.is-loading):hover::after { + border-color: #363636; +} + +.select.is-white:not(:hover)::after { + border-color: white; +} + +.select.is-white select { + border-color: white; +} + +.select.is-white select:hover, .select.is-white select.is-hovered { + border-color: #f2f2f2; +} + +.select.is-white select:focus, .select.is-white select.is-focused, .select.is-white select:active, .select.is-white select.is-active { + box-shadow: 0 0 0 0.125em rgba(255, 255, 255, 0.25); +} + +.select.is-black:not(:hover)::after { + border-color: #0a0a0a; +} + +.select.is-black select { + border-color: #0a0a0a; +} + +.select.is-black select:hover, .select.is-black select.is-hovered { + border-color: black; +} + +.select.is-black select:focus, .select.is-black select.is-focused, .select.is-black select:active, .select.is-black select.is-active { + box-shadow: 0 0 0 0.125em rgba(10, 10, 10, 0.25); +} + +.select.is-light:not(:hover)::after { + border-color: whitesmoke; +} + +.select.is-light select { + border-color: whitesmoke; +} + +.select.is-light select:hover, .select.is-light select.is-hovered { + border-color: #e8e8e8; +} + +.select.is-light select:focus, .select.is-light select.is-focused, .select.is-light select:active, .select.is-light select.is-active { + box-shadow: 0 0 0 0.125em rgba(245, 245, 245, 0.25); +} + +.select.is-dark:not(:hover)::after { + border-color: #363636; +} + +.select.is-dark select { + border-color: #363636; +} + +.select.is-dark select:hover, .select.is-dark select.is-hovered { + border-color: #292929; +} + +.select.is-dark select:focus, .select.is-dark select.is-focused, .select.is-dark select:active, .select.is-dark select.is-active { + box-shadow: 0 0 0 0.125em rgba(54, 54, 54, 0.25); +} + +.select.is-primary:not(:hover)::after { + border-color: #00d1b2; +} + +.select.is-primary select { + border-color: #00d1b2; +} + +.select.is-primary select:hover, .select.is-primary select.is-hovered { + border-color: #00b89c; +} + +.select.is-primary select:focus, .select.is-primary select.is-focused, .select.is-primary select:active, .select.is-primary select.is-active { + box-shadow: 0 0 0 0.125em rgba(0, 209, 178, 0.25); +} + +.select.is-link:not(:hover)::after { + border-color: #3273dc; +} + +.select.is-link select { + border-color: #3273dc; +} + +.select.is-link select:hover, .select.is-link select.is-hovered { + border-color: #2366d1; +} + +.select.is-link select:focus, .select.is-link select.is-focused, .select.is-link select:active, .select.is-link select.is-active { + box-shadow: 0 0 0 0.125em rgba(50, 115, 220, 0.25); +} + +.select.is-info:not(:hover)::after { + border-color: #3298dc; +} + +.select.is-info select { + border-color: #3298dc; +} + +.select.is-info select:hover, .select.is-info select.is-hovered { + border-color: #238cd1; +} + +.select.is-info select:focus, .select.is-info select.is-focused, .select.is-info select:active, .select.is-info select.is-active { + box-shadow: 0 0 0 0.125em rgba(50, 152, 220, 0.25); +} + +.select.is-success:not(:hover)::after { + border-color: #48c774; +} + +.select.is-success select { + border-color: #48c774; +} + +.select.is-success select:hover, .select.is-success select.is-hovered { + border-color: #3abb67; +} + +.select.is-success select:focus, .select.is-success select.is-focused, .select.is-success select:active, .select.is-success select.is-active { + box-shadow: 0 0 0 0.125em rgba(72, 199, 116, 0.25); +} + +.select.is-warning:not(:hover)::after { + border-color: #ffdd57; +} + +.select.is-warning select { + border-color: #ffdd57; +} + +.select.is-warning select:hover, .select.is-warning select.is-hovered { + border-color: #ffd83d; +} + +.select.is-warning select:focus, .select.is-warning select.is-focused, .select.is-warning select:active, .select.is-warning select.is-active { + box-shadow: 0 0 0 0.125em rgba(255, 221, 87, 0.25); +} + +.select.is-danger:not(:hover)::after { + border-color: #f14668; +} + +.select.is-danger select { + border-color: #f14668; +} + +.select.is-danger select:hover, .select.is-danger select.is-hovered { + border-color: #ef2e55; +} + +.select.is-danger select:focus, .select.is-danger select.is-focused, .select.is-danger select:active, .select.is-danger select.is-active { + box-shadow: 0 0 0 0.125em rgba(241, 70, 104, 0.25); +} + +.select.is-small { + border-radius: 2px; + font-size: 0.75rem; +} + +.select.is-medium { + font-size: 1.25rem; +} + +.select.is-large { + font-size: 1.5rem; +} + +.select.is-disabled::after { + border-color: #7a7a7a; +} + +.select.is-fullwidth { + width: 100%; +} + +.select.is-fullwidth select { + width: 100%; +} + +.select.is-loading::after { + margin-top: 0; + position: absolute; + right: 0.625em; + top: 0.625em; + transform: none; +} + +.select.is-loading.is-small:after { + font-size: 0.75rem; +} + +.select.is-loading.is-medium:after { + font-size: 1.25rem; +} + +.select.is-loading.is-large:after { + font-size: 1.5rem; +} + +.file { + align-items: stretch; + display: flex; + justify-content: flex-start; + position: relative; +} + +.file.is-white .file-cta { + background-color: white; + border-color: transparent; + color: #0a0a0a; +} + +.file.is-white:hover .file-cta, .file.is-white.is-hovered .file-cta { + background-color: #f9f9f9; + border-color: transparent; + color: #0a0a0a; +} + +.file.is-white:focus .file-cta, .file.is-white.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(255, 255, 255, 0.25); + color: #0a0a0a; +} + +.file.is-white:active .file-cta, .file.is-white.is-active .file-cta { + background-color: #f2f2f2; + border-color: transparent; + color: #0a0a0a; +} + +.file.is-black .file-cta { + background-color: #0a0a0a; + border-color: transparent; + color: white; +} + +.file.is-black:hover .file-cta, .file.is-black.is-hovered .file-cta { + background-color: #040404; + border-color: transparent; + color: white; +} + +.file.is-black:focus .file-cta, .file.is-black.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(10, 10, 10, 0.25); + color: white; +} + +.file.is-black:active .file-cta, .file.is-black.is-active .file-cta { + background-color: black; + border-color: transparent; + color: white; +} + +.file.is-light .file-cta { + background-color: whitesmoke; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-light:hover .file-cta, .file.is-light.is-hovered .file-cta { + background-color: #eeeeee; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-light:focus .file-cta, .file.is-light.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(245, 245, 245, 0.25); + color: rgba(0, 0, 0, 0.7); +} + +.file.is-light:active .file-cta, .file.is-light.is-active .file-cta { + background-color: #e8e8e8; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-dark .file-cta { + background-color: #363636; + border-color: transparent; + color: #fff; +} + +.file.is-dark:hover .file-cta, .file.is-dark.is-hovered .file-cta { + background-color: #2f2f2f; + border-color: transparent; + color: #fff; +} + +.file.is-dark:focus .file-cta, .file.is-dark.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(54, 54, 54, 0.25); + color: #fff; +} + +.file.is-dark:active .file-cta, .file.is-dark.is-active .file-cta { + background-color: #292929; + border-color: transparent; + color: #fff; +} + +.file.is-primary .file-cta { + background-color: #00d1b2; + border-color: transparent; + color: #fff; +} + +.file.is-primary:hover .file-cta, .file.is-primary.is-hovered .file-cta { + background-color: #00c4a7; + border-color: transparent; + color: #fff; +} + +.file.is-primary:focus .file-cta, .file.is-primary.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(0, 209, 178, 0.25); + color: #fff; +} + +.file.is-primary:active .file-cta, .file.is-primary.is-active .file-cta { + background-color: #00b89c; + border-color: transparent; + color: #fff; +} + +.file.is-link .file-cta { + background-color: #3273dc; + border-color: transparent; + color: #fff; +} + +.file.is-link:hover .file-cta, .file.is-link.is-hovered .file-cta { + background-color: #276cda; + border-color: transparent; + color: #fff; +} + +.file.is-link:focus .file-cta, .file.is-link.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(50, 115, 220, 0.25); + color: #fff; +} + +.file.is-link:active .file-cta, .file.is-link.is-active .file-cta { + background-color: #2366d1; + border-color: transparent; + color: #fff; +} + +.file.is-info .file-cta { + background-color: #3298dc; + border-color: transparent; + color: #fff; +} + +.file.is-info:hover .file-cta, .file.is-info.is-hovered .file-cta { + background-color: #2793da; + border-color: transparent; + color: #fff; +} + +.file.is-info:focus .file-cta, .file.is-info.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(50, 152, 220, 0.25); + color: #fff; +} + +.file.is-info:active .file-cta, .file.is-info.is-active .file-cta { + background-color: #238cd1; + border-color: transparent; + color: #fff; +} + +.file.is-success .file-cta { + background-color: #48c774; + border-color: transparent; + color: #fff; +} + +.file.is-success:hover .file-cta, .file.is-success.is-hovered .file-cta { + background-color: #3ec46d; + border-color: transparent; + color: #fff; +} + +.file.is-success:focus .file-cta, .file.is-success.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(72, 199, 116, 0.25); + color: #fff; +} + +.file.is-success:active .file-cta, .file.is-success.is-active .file-cta { + background-color: #3abb67; + border-color: transparent; + color: #fff; +} + +.file.is-warning .file-cta { + background-color: #ffdd57; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-warning:hover .file-cta, .file.is-warning.is-hovered .file-cta { + background-color: #ffdb4a; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-warning:focus .file-cta, .file.is-warning.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(255, 221, 87, 0.25); + color: rgba(0, 0, 0, 0.7); +} + +.file.is-warning:active .file-cta, .file.is-warning.is-active .file-cta { + background-color: #ffd83d; + border-color: transparent; + color: rgba(0, 0, 0, 0.7); +} + +.file.is-danger .file-cta { + background-color: #f14668; + border-color: transparent; + color: #fff; +} + +.file.is-danger:hover .file-cta, .file.is-danger.is-hovered .file-cta { + background-color: #f03a5f; + border-color: transparent; + color: #fff; +} + +.file.is-danger:focus .file-cta, .file.is-danger.is-focused .file-cta { + border-color: transparent; + box-shadow: 0 0 0.5em rgba(241, 70, 104, 0.25); + color: #fff; +} + +.file.is-danger:active .file-cta, .file.is-danger.is-active .file-cta { + background-color: #ef2e55; + border-color: transparent; + color: #fff; +} + +.file.is-small { + font-size: 0.75rem; +} + +.file.is-medium { + font-size: 1.25rem; +} + +.file.is-medium .file-icon .fa { + font-size: 21px; +} + +.file.is-large { + font-size: 1.5rem; +} + +.file.is-large .file-icon .fa { + font-size: 28px; +} + +.file.has-name .file-cta { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.file.has-name .file-name { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.file.has-name.is-empty .file-cta { + border-radius: 4px; +} + +.file.has-name.is-empty .file-name { + display: none; +} + +.file.is-boxed .file-label { + flex-direction: column; +} + +.file.is-boxed .file-cta { + flex-direction: column; + height: auto; + padding: 1em 3em; +} + +.file.is-boxed .file-name { + border-width: 0 1px 1px; +} + +.file.is-boxed .file-icon { + height: 1.5em; + width: 1.5em; +} + +.file.is-boxed .file-icon .fa { + font-size: 21px; +} + +.file.is-boxed.is-small .file-icon .fa { + font-size: 14px; +} + +.file.is-boxed.is-medium .file-icon .fa { + font-size: 28px; +} + +.file.is-boxed.is-large .file-icon .fa { + font-size: 35px; +} + +.file.is-boxed.has-name .file-cta { + border-radius: 4px 4px 0 0; +} + +.file.is-boxed.has-name .file-name { + border-radius: 0 0 4px 4px; + border-width: 0 1px 1px; +} + +.file.is-centered { + justify-content: center; +} + +.file.is-fullwidth .file-label { + width: 100%; +} + +.file.is-fullwidth .file-name { + flex-grow: 1; + max-width: none; +} + +.file.is-right { + justify-content: flex-end; +} + +.file.is-right .file-cta { + border-radius: 0 4px 4px 0; +} + +.file.is-right .file-name { + border-radius: 4px 0 0 4px; + border-width: 1px 0 1px 1px; + order: -1; +} + +.file-label { + align-items: stretch; + display: flex; + cursor: pointer; + justify-content: flex-start; + overflow: hidden; + position: relative; +} + +.file-label:hover .file-cta { + background-color: #eeeeee; + color: #363636; +} + +.file-label:hover .file-name { + border-color: #d5d5d5; +} + +.file-label:active .file-cta { + background-color: #e8e8e8; + color: #363636; +} + +.file-label:active .file-name { + border-color: #cfcfcf; +} + +.file-input { + height: 100%; + left: 0; + opacity: 0; + outline: none; + position: absolute; + top: 0; + width: 100%; +} + +.file-cta, +.file-name { + border-color: #dbdbdb; + border-radius: 4px; + font-size: 1em; + padding-left: 1em; + padding-right: 1em; + white-space: nowrap; +} + +.file-cta { + background-color: whitesmoke; + color: #4a4a4a; +} + +.file-name { + border-color: #dbdbdb; + border-style: solid; + border-width: 1px 1px 1px 0; + display: block; + max-width: 16em; + overflow: hidden; + text-align: inherit; + text-overflow: ellipsis; +} + +.file-icon { + align-items: center; + display: flex; + height: 1em; + justify-content: center; + margin-right: 0.5em; + width: 1em; +} + +.file-icon .fa { + font-size: 14px; +} + +.label { + color: #363636; + display: block; + font-size: 1rem; + font-weight: 700; +} + +.label:not(:last-child) { + margin-bottom: 0.5em; +} + +.label.is-small { + font-size: 0.75rem; +} + +.label.is-medium { + font-size: 1.25rem; +} + +.label.is-large { + font-size: 1.5rem; +} + +.help { + display: block; + font-size: 0.75rem; + margin-top: 0.25rem; +} + +.help.is-white { + color: white; +} + +.help.is-black { + color: #0a0a0a; +} + +.help.is-light { + color: whitesmoke; +} + +.help.is-dark { + color: #363636; +} + +.help.is-primary { + color: #00d1b2; +} + +.help.is-link { + color: #3273dc; +} + +.help.is-info { + color: #3298dc; +} + +.help.is-success { + color: #48c774; +} + +.help.is-warning { + color: #ffdd57; +} + +.help.is-danger { + color: #f14668; +} + +.field:not(:last-child) { + margin-bottom: 0.75rem; +} + +.field.has-addons { + display: flex; + justify-content: flex-start; +} + +.field.has-addons .control:not(:last-child) { + margin-right: -1px; +} + +.field.has-addons .control:not(:first-child):not(:last-child) .button, +.field.has-addons .control:not(:first-child):not(:last-child) .input, +.field.has-addons .control:not(:first-child):not(:last-child) .select select { + border-radius: 0; +} + +.field.has-addons .control:first-child:not(:only-child) .button, +.field.has-addons .control:first-child:not(:only-child) .input, +.field.has-addons .control:first-child:not(:only-child) .select select { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} + +.field.has-addons .control:last-child:not(:only-child) .button, +.field.has-addons .control:last-child:not(:only-child) .input, +.field.has-addons .control:last-child:not(:only-child) .select select { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} + +.field.has-addons .control .button:not([disabled]):hover, .field.has-addons .control .button:not([disabled]).is-hovered, +.field.has-addons .control .input:not([disabled]):hover, +.field.has-addons .control .input:not([disabled]).is-hovered, +.field.has-addons .control .select select:not([disabled]):hover, +.field.has-addons .control .select select:not([disabled]).is-hovered { + z-index: 2; +} + +.field.has-addons .control .button:not([disabled]):focus, .field.has-addons .control .button:not([disabled]).is-focused, .field.has-addons .control .button:not([disabled]):active, .field.has-addons .control .button:not([disabled]).is-active, +.field.has-addons .control .input:not([disabled]):focus, +.field.has-addons .control .input:not([disabled]).is-focused, +.field.has-addons .control .input:not([disabled]):active, +.field.has-addons .control .input:not([disabled]).is-active, +.field.has-addons .control .select select:not([disabled]):focus, +.field.has-addons .control .select select:not([disabled]).is-focused, +.field.has-addons .control .select select:not([disabled]):active, +.field.has-addons .control .select select:not([disabled]).is-active { + z-index: 3; +} + +.field.has-addons .control .button:not([disabled]):focus:hover, .field.has-addons .control .button:not([disabled]).is-focused:hover, .field.has-addons .control .button:not([disabled]):active:hover, .field.has-addons .control .button:not([disabled]).is-active:hover, +.field.has-addons .control .input:not([disabled]):focus:hover, +.field.has-addons .control .input:not([disabled]).is-focused:hover, +.field.has-addons .control .input:not([disabled]):active:hover, +.field.has-addons .control .input:not([disabled]).is-active:hover, +.field.has-addons .control .select select:not([disabled]):focus:hover, +.field.has-addons .control .select select:not([disabled]).is-focused:hover, +.field.has-addons .control .select select:not([disabled]):active:hover, +.field.has-addons .control .select select:not([disabled]).is-active:hover { + z-index: 4; +} + +.field.has-addons .control.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.field.has-addons.has-addons-centered { + justify-content: center; +} + +.field.has-addons.has-addons-right { + justify-content: flex-end; +} + +.field.has-addons.has-addons-fullwidth .control { + flex-grow: 1; + flex-shrink: 0; +} + +.field.is-grouped { + display: flex; + justify-content: flex-start; +} + +.field.is-grouped > .control { + flex-shrink: 0; +} + +.field.is-grouped > .control:not(:last-child) { + margin-bottom: 0; + margin-right: 0.75rem; +} + +.field.is-grouped > .control.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.field.is-grouped.is-grouped-centered { + justify-content: center; +} + +.field.is-grouped.is-grouped-right { + justify-content: flex-end; +} + +.field.is-grouped.is-grouped-multiline { + flex-wrap: wrap; +} + +.field.is-grouped.is-grouped-multiline > .control:last-child, .field.is-grouped.is-grouped-multiline > .control:not(:last-child) { + margin-bottom: 0.75rem; +} + +.field.is-grouped.is-grouped-multiline:last-child { + margin-bottom: -0.75rem; +} + +.field.is-grouped.is-grouped-multiline:not(:last-child) { + margin-bottom: 0; +} + +@media screen and (min-width: 769px), print { + .field.is-horizontal { + display: flex; + } +} + +.field-label .label { + font-size: inherit; +} + +@media screen and (max-width: 768px) { + .field-label { + margin-bottom: 0.5rem; + } +} + +@media screen and (min-width: 769px), print { + .field-label { + flex-basis: 0; + flex-grow: 1; + flex-shrink: 0; + margin-right: 1.5rem; + text-align: right; + } + .field-label.is-small { + font-size: 0.75rem; + padding-top: 0.375em; + } + .field-label.is-normal { + padding-top: 0.375em; + } + .field-label.is-medium { + font-size: 1.25rem; + padding-top: 0.375em; + } + .field-label.is-large { + font-size: 1.5rem; + padding-top: 0.375em; + } +} + +.field-body .field .field { + margin-bottom: 0; +} + +@media screen and (min-width: 769px), print { + .field-body { + display: flex; + flex-basis: 0; + flex-grow: 5; + flex-shrink: 1; + } + .field-body .field { + margin-bottom: 0; + } + .field-body > .field { + flex-shrink: 1; + } + .field-body > .field:not(.is-narrow) { + flex-grow: 1; + } + .field-body > .field:not(:last-child) { + margin-right: 0.75rem; + } +} + +.control { + box-sizing: border-box; + clear: both; + font-size: 1rem; + position: relative; + text-align: inherit; +} + +.control.has-icons-left .input:focus ~ .icon, +.control.has-icons-left .select:focus ~ .icon, .control.has-icons-right .input:focus ~ .icon, +.control.has-icons-right .select:focus ~ .icon { + color: #4a4a4a; +} + +.control.has-icons-left .input.is-small ~ .icon, +.control.has-icons-left .select.is-small ~ .icon, .control.has-icons-right .input.is-small ~ .icon, +.control.has-icons-right .select.is-small ~ .icon { + font-size: 0.75rem; +} + +.control.has-icons-left .input.is-medium ~ .icon, +.control.has-icons-left .select.is-medium ~ .icon, .control.has-icons-right .input.is-medium ~ .icon, +.control.has-icons-right .select.is-medium ~ .icon { + font-size: 1.25rem; +} + +.control.has-icons-left .input.is-large ~ .icon, +.control.has-icons-left .select.is-large ~ .icon, .control.has-icons-right .input.is-large ~ .icon, +.control.has-icons-right .select.is-large ~ .icon { + font-size: 1.5rem; +} + +.control.has-icons-left .icon, .control.has-icons-right .icon { + color: #dbdbdb; + height: 2.5em; + pointer-events: none; + position: absolute; + top: 0; + width: 2.5em; + z-index: 4; +} + +.control.has-icons-left .input, +.control.has-icons-left .select select { + padding-left: 2.5em; +} + +.control.has-icons-left .icon.is-left { + left: 0; +} + +.control.has-icons-right .input, +.control.has-icons-right .select select { + padding-right: 2.5em; +} + +.control.has-icons-right .icon.is-right { + right: 0; +} + +.control.is-loading::after { + position: absolute !important; + right: 0.625em; + top: 0.625em; + z-index: 4; +} + +.control.is-loading.is-small:after { + font-size: 0.75rem; +} + +.control.is-loading.is-medium:after { + font-size: 1.25rem; +} + +.control.is-loading.is-large:after { + font-size: 1.5rem; +} + +.breadcrumb { + font-size: 1rem; + white-space: nowrap; +} + +.breadcrumb a { + align-items: center; + color: #3273dc; + display: flex; + justify-content: center; + padding: 0 0.75em; +} + +.breadcrumb a:hover { + color: #363636; +} + +.breadcrumb li { + align-items: center; + display: flex; +} + +.breadcrumb li:first-child a { + padding-left: 0; +} + +.breadcrumb li.is-active a { + color: #363636; + cursor: default; + pointer-events: none; +} + +.breadcrumb li + li::before { + color: #b5b5b5; + content: "\0002f"; +} + +.breadcrumb ul, +.breadcrumb ol { + align-items: flex-start; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} + +.breadcrumb .icon:first-child { + margin-right: 0.5em; +} + +.breadcrumb .icon:last-child { + margin-left: 0.5em; +} + +.breadcrumb.is-centered ol, +.breadcrumb.is-centered ul { + justify-content: center; +} + +.breadcrumb.is-right ol, +.breadcrumb.is-right ul { + justify-content: flex-end; +} + +.breadcrumb.is-small { + font-size: 0.75rem; +} + +.breadcrumb.is-medium { + font-size: 1.25rem; +} + +.breadcrumb.is-large { + font-size: 1.5rem; +} + +.breadcrumb.has-arrow-separator li + li::before { + content: "\02192"; +} + +.breadcrumb.has-bullet-separator li + li::before { + content: "\02022"; +} + +.breadcrumb.has-dot-separator li + li::before { + content: "\000b7"; +} + +.breadcrumb.has-succeeds-separator li + li::before { + content: "\0227B"; +} + +.card { + background-color: white; + box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02); + color: #4a4a4a; + max-width: 100%; + position: relative; +} + +.card-header { + background-color: transparent; + align-items: stretch; + box-shadow: 0 0.125em 0.25em rgba(10, 10, 10, 0.1); + display: flex; +} + +.card-header-title { + align-items: center; + color: #363636; + display: flex; + flex-grow: 1; + font-weight: 700; + padding: 0.75rem 1rem; +} + +.card-header-title.is-centered { + justify-content: center; +} + +.card-header-icon { + align-items: center; + cursor: pointer; + display: flex; + justify-content: center; + padding: 0.75rem 1rem; +} + +.card-image { + display: block; + position: relative; +} + +.card-content { + background-color: transparent; + padding: 1.5rem; +} + +.card-footer { + background-color: transparent; + border-top: 1px solid #ededed; + align-items: stretch; + display: flex; +} + +.card-footer-item { + align-items: center; + display: flex; + flex-basis: 0; + flex-grow: 1; + flex-shrink: 0; + justify-content: center; + padding: 0.75rem; +} + +.card-footer-item:not(:last-child) { + border-right: 1px solid #ededed; +} + +.card .media:not(:last-child) { + margin-bottom: 1.5rem; +} + +.dropdown { + display: inline-flex; + position: relative; + vertical-align: top; +} + +.dropdown.is-active .dropdown-menu, .dropdown.is-hoverable:hover .dropdown-menu { + display: block; +} + +.dropdown.is-right .dropdown-menu { + left: auto; + right: 0; +} + +.dropdown.is-up .dropdown-menu { + bottom: 100%; + padding-bottom: 4px; + padding-top: initial; + top: auto; +} + +.dropdown-menu { + display: none; + left: 0; + min-width: 12rem; + padding-top: 4px; + position: absolute; + top: 100%; + z-index: 20; +} + +.dropdown-content { + background-color: white; + border-radius: 4px; + box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02); + padding-bottom: 0.5rem; + padding-top: 0.5rem; +} + +.dropdown-item { + color: #4a4a4a; + display: block; + font-size: 0.875rem; + line-height: 1.5; + padding: 0.375rem 1rem; + position: relative; +} + +a.dropdown-item, +button.dropdown-item { + padding-right: 3rem; + text-align: inherit; + white-space: nowrap; + width: 100%; +} + +a.dropdown-item:hover, +button.dropdown-item:hover { + background-color: whitesmoke; + color: #0a0a0a; +} + +a.dropdown-item.is-active, +button.dropdown-item.is-active { + background-color: #3273dc; + color: #fff; +} + +.dropdown-divider { + background-color: #ededed; + border: none; + display: block; + height: 1px; + margin: 0.5rem 0; +} + +.level { + align-items: center; + justify-content: space-between; +} + +.level code { + border-radius: 4px; +} + +.level img { + display: inline-block; + vertical-align: top; +} + +.level.is-mobile { + display: flex; +} + +.level.is-mobile .level-left, +.level.is-mobile .level-right { + display: flex; +} + +.level.is-mobile .level-left + .level-right { + margin-top: 0; +} + +.level.is-mobile .level-item:not(:last-child) { + margin-bottom: 0; + margin-right: 0.75rem; +} + +.level.is-mobile .level-item:not(.is-narrow) { + flex-grow: 1; +} + +@media screen and (min-width: 769px), print { + .level { + display: flex; + } + .level > .level-item:not(.is-narrow) { + flex-grow: 1; + } +} + +.level-item { + align-items: center; + display: flex; + flex-basis: auto; + flex-grow: 0; + flex-shrink: 0; + justify-content: center; +} + +.level-item .title, +.level-item .subtitle { + margin-bottom: 0; +} + +@media screen and (max-width: 768px) { + .level-item:not(:last-child) { + margin-bottom: 0.75rem; + } +} + +.level-left, +.level-right { + flex-basis: auto; + flex-grow: 0; + flex-shrink: 0; +} + +.level-left .level-item.is-flexible, +.level-right .level-item.is-flexible { + flex-grow: 1; +} + +@media screen and (min-width: 769px), print { + .level-left .level-item:not(:last-child), + .level-right .level-item:not(:last-child) { + margin-right: 0.75rem; + } +} + +.level-left { + align-items: center; + justify-content: flex-start; +} + +@media screen and (max-width: 768px) { + .level-left + .level-right { + margin-top: 1.5rem; + } +} + +@media screen and (min-width: 769px), print { + .level-left { + display: flex; + } +} + +.level-right { + align-items: center; + justify-content: flex-end; +} + +@media screen and (min-width: 769px), print { + .level-right { + display: flex; + } +} + +.media { + align-items: flex-start; + display: flex; + text-align: inherit; +} + +.media .content:not(:last-child) { + margin-bottom: 0.75rem; +} + +.media .media { + border-top: 1px solid rgba(219, 219, 219, 0.5); + display: flex; + padding-top: 0.75rem; +} + +.media .media .content:not(:last-child), +.media .media .control:not(:last-child) { + margin-bottom: 0.5rem; +} + +.media .media .media { + padding-top: 0.5rem; +} + +.media .media .media + .media { + margin-top: 0.5rem; +} + +.media + .media { + border-top: 1px solid rgba(219, 219, 219, 0.5); + margin-top: 1rem; + padding-top: 1rem; +} + +.media.is-large + .media { + margin-top: 1.5rem; + padding-top: 1.5rem; +} + +.media-left, +.media-right { + flex-basis: auto; + flex-grow: 0; + flex-shrink: 0; +} + +.media-left { + margin-right: 1rem; +} + +.media-right { + margin-left: 1rem; +} + +.media-content { + flex-basis: auto; + flex-grow: 1; + flex-shrink: 1; + text-align: inherit; +} + +@media screen and (max-width: 768px) { + .media-content { + overflow-x: auto; + } +} + +.menu { + font-size: 1rem; +} + +.menu.is-small { + font-size: 0.75rem; +} + +.menu.is-medium { + font-size: 1.25rem; +} + +.menu.is-large { + font-size: 1.5rem; +} + +.menu-list { + line-height: 1.25; +} + +.menu-list a { + border-radius: 2px; + color: #4a4a4a; + display: block; + padding: 0.5em 0.75em; +} + +.menu-list a:hover { + background-color: whitesmoke; + color: #363636; +} + +.menu-list a.is-active { + background-color: #3273dc; + color: #fff; +} + +.menu-list li ul { + border-left: 1px solid #dbdbdb; + margin: 0.75em; + padding-left: 0.75em; +} + +.menu-label { + color: #7a7a7a; + font-size: 0.75em; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.menu-label:not(:first-child) { + margin-top: 1em; +} + +.menu-label:not(:last-child) { + margin-bottom: 1em; +} + +.message { + background-color: whitesmoke; + border-radius: 4px; + font-size: 1rem; +} + +.message strong { + color: currentColor; +} + +.message a:not(.button):not(.tag):not(.dropdown-item) { + color: currentColor; + text-decoration: underline; +} + +.message.is-small { + font-size: 0.75rem; +} + +.message.is-medium { + font-size: 1.25rem; +} + +.message.is-large { + font-size: 1.5rem; +} + +.message.is-white { + background-color: white; +} + +.message.is-white .message-header { + background-color: white; + color: #0a0a0a; +} + +.message.is-white .message-body { + border-color: white; +} + +.message.is-black { + background-color: #fafafa; +} + +.message.is-black .message-header { + background-color: #0a0a0a; + color: white; +} + +.message.is-black .message-body { + border-color: #0a0a0a; +} + +.message.is-light { + background-color: #fafafa; +} + +.message.is-light .message-header { + background-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.message.is-light .message-body { + border-color: whitesmoke; +} + +.message.is-dark { + background-color: #fafafa; +} + +.message.is-dark .message-header { + background-color: #363636; + color: #fff; +} + +.message.is-dark .message-body { + border-color: #363636; +} + +.message.is-primary { + background-color: #ebfffc; +} + +.message.is-primary .message-header { + background-color: #00d1b2; + color: #fff; +} + +.message.is-primary .message-body { + border-color: #00d1b2; + color: #00947e; +} + +.message.is-link { + background-color: #eef3fc; +} + +.message.is-link .message-header { + background-color: #3273dc; + color: #fff; +} + +.message.is-link .message-body { + border-color: #3273dc; + color: #2160c4; +} + +.message.is-info { + background-color: #eef6fc; +} + +.message.is-info .message-header { + background-color: #3298dc; + color: #fff; +} + +.message.is-info .message-body { + border-color: #3298dc; + color: #1d72aa; +} + +.message.is-success { + background-color: #effaf3; +} + +.message.is-success .message-header { + background-color: #48c774; + color: #fff; +} + +.message.is-success .message-body { + border-color: #48c774; + color: #257942; +} + +.message.is-warning { + background-color: #fffbeb; +} + +.message.is-warning .message-header { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.message.is-warning .message-body { + border-color: #ffdd57; + color: #947600; +} + +.message.is-danger { + background-color: #feecf0; +} + +.message.is-danger .message-header { + background-color: #f14668; + color: #fff; +} + +.message.is-danger .message-body { + border-color: #f14668; + color: #cc0f35; +} + +.message-header { + align-items: center; + background-color: #4a4a4a; + border-radius: 4px 4px 0 0; + color: #fff; + display: flex; + font-weight: 700; + justify-content: space-between; + line-height: 1.25; + padding: 0.75em 1em; + position: relative; +} + +.message-header .delete { + flex-grow: 0; + flex-shrink: 0; + margin-left: 0.75em; +} + +.message-header + .message-body { + border-width: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.message-body { + border-color: #dbdbdb; + border-radius: 4px; + border-style: solid; + border-width: 0 0 0 4px; + color: #4a4a4a; + padding: 1.25em 1.5em; +} + +.message-body code, +.message-body pre { + background-color: white; +} + +.message-body pre code { + background-color: transparent; +} + +.modal { + align-items: center; + display: none; + flex-direction: column; + justify-content: center; + overflow: hidden; + position: fixed; + z-index: 40; +} + +.modal.is-active { + display: flex; +} + +.modal-background { + background-color: rgba(10, 10, 10, 0.86); +} + +.modal-content, +.modal-card { + margin: 0 20px; + max-height: calc(100vh - 160px); + overflow: auto; + position: relative; + width: 100%; +} + +@media screen and (min-width: 769px), print { + .modal-content, + .modal-card { + margin: 0 auto; + max-height: calc(100vh - 40px); + width: 640px; + } +} + +.modal-close { + background: none; + height: 40px; + position: fixed; + right: 20px; + top: 20px; + width: 40px; +} + +.modal-card { + display: flex; + flex-direction: column; + max-height: calc(100vh - 40px); + overflow: hidden; + -ms-overflow-y: visible; +} + +.modal-card-head, +.modal-card-foot { + align-items: center; + background-color: whitesmoke; + display: flex; + flex-shrink: 0; + justify-content: flex-start; + padding: 20px; + position: relative; +} + +.modal-card-head { + border-bottom: 1px solid #dbdbdb; + border-top-left-radius: 6px; + border-top-right-radius: 6px; +} + +.modal-card-title { + color: #363636; + flex-grow: 1; + flex-shrink: 0; + font-size: 1.5rem; + line-height: 1; +} + +.modal-card-foot { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-top: 1px solid #dbdbdb; +} + +.modal-card-foot .button:not(:last-child) { + margin-right: 0.5em; +} + +.modal-card-body { + -webkit-overflow-scrolling: touch; + background-color: white; + flex-grow: 1; + flex-shrink: 1; + overflow: auto; + padding: 20px; +} + +.navbar { + background-color: white; + min-height: 3.25rem; + position: relative; + z-index: 30; +} + +.navbar.is-white { + background-color: white; + color: #0a0a0a; +} + +.navbar.is-white .navbar-brand > .navbar-item, +.navbar.is-white .navbar-brand .navbar-link { + color: #0a0a0a; +} + +.navbar.is-white .navbar-brand > a.navbar-item:focus, .navbar.is-white .navbar-brand > a.navbar-item:hover, .navbar.is-white .navbar-brand > a.navbar-item.is-active, +.navbar.is-white .navbar-brand .navbar-link:focus, +.navbar.is-white .navbar-brand .navbar-link:hover, +.navbar.is-white .navbar-brand .navbar-link.is-active { + background-color: #f2f2f2; + color: #0a0a0a; +} + +.navbar.is-white .navbar-brand .navbar-link::after { + border-color: #0a0a0a; +} + +.navbar.is-white .navbar-burger { + color: #0a0a0a; +} + +@media screen and (min-width: 1024px) { + .navbar.is-white .navbar-start > .navbar-item, + .navbar.is-white .navbar-start .navbar-link, + .navbar.is-white .navbar-end > .navbar-item, + .navbar.is-white .navbar-end .navbar-link { + color: #0a0a0a; + } + .navbar.is-white .navbar-start > a.navbar-item:focus, .navbar.is-white .navbar-start > a.navbar-item:hover, .navbar.is-white .navbar-start > a.navbar-item.is-active, + .navbar.is-white .navbar-start .navbar-link:focus, + .navbar.is-white .navbar-start .navbar-link:hover, + .navbar.is-white .navbar-start .navbar-link.is-active, + .navbar.is-white .navbar-end > a.navbar-item:focus, + .navbar.is-white .navbar-end > a.navbar-item:hover, + .navbar.is-white .navbar-end > a.navbar-item.is-active, + .navbar.is-white .navbar-end .navbar-link:focus, + .navbar.is-white .navbar-end .navbar-link:hover, + .navbar.is-white .navbar-end .navbar-link.is-active { + background-color: #f2f2f2; + color: #0a0a0a; + } + .navbar.is-white .navbar-start .navbar-link::after, + .navbar.is-white .navbar-end .navbar-link::after { + border-color: #0a0a0a; + } + .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #f2f2f2; + color: #0a0a0a; + } + .navbar.is-white .navbar-dropdown a.navbar-item.is-active { + background-color: white; + color: #0a0a0a; + } +} + +.navbar.is-black { + background-color: #0a0a0a; + color: white; +} + +.navbar.is-black .navbar-brand > .navbar-item, +.navbar.is-black .navbar-brand .navbar-link { + color: white; +} + +.navbar.is-black .navbar-brand > a.navbar-item:focus, .navbar.is-black .navbar-brand > a.navbar-item:hover, .navbar.is-black .navbar-brand > a.navbar-item.is-active, +.navbar.is-black .navbar-brand .navbar-link:focus, +.navbar.is-black .navbar-brand .navbar-link:hover, +.navbar.is-black .navbar-brand .navbar-link.is-active { + background-color: black; + color: white; +} + +.navbar.is-black .navbar-brand .navbar-link::after { + border-color: white; +} + +.navbar.is-black .navbar-burger { + color: white; +} + +@media screen and (min-width: 1024px) { + .navbar.is-black .navbar-start > .navbar-item, + .navbar.is-black .navbar-start .navbar-link, + .navbar.is-black .navbar-end > .navbar-item, + .navbar.is-black .navbar-end .navbar-link { + color: white; + } + .navbar.is-black .navbar-start > a.navbar-item:focus, .navbar.is-black .navbar-start > a.navbar-item:hover, .navbar.is-black .navbar-start > a.navbar-item.is-active, + .navbar.is-black .navbar-start .navbar-link:focus, + .navbar.is-black .navbar-start .navbar-link:hover, + .navbar.is-black .navbar-start .navbar-link.is-active, + .navbar.is-black .navbar-end > a.navbar-item:focus, + .navbar.is-black .navbar-end > a.navbar-item:hover, + .navbar.is-black .navbar-end > a.navbar-item.is-active, + .navbar.is-black .navbar-end .navbar-link:focus, + .navbar.is-black .navbar-end .navbar-link:hover, + .navbar.is-black .navbar-end .navbar-link.is-active { + background-color: black; + color: white; + } + .navbar.is-black .navbar-start .navbar-link::after, + .navbar.is-black .navbar-end .navbar-link::after { + border-color: white; + } + .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link { + background-color: black; + color: white; + } + .navbar.is-black .navbar-dropdown a.navbar-item.is-active { + background-color: #0a0a0a; + color: white; + } +} + +.navbar.is-light { + background-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-light .navbar-brand > .navbar-item, +.navbar.is-light .navbar-brand .navbar-link { + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-light .navbar-brand > a.navbar-item:focus, .navbar.is-light .navbar-brand > a.navbar-item:hover, .navbar.is-light .navbar-brand > a.navbar-item.is-active, +.navbar.is-light .navbar-brand .navbar-link:focus, +.navbar.is-light .navbar-brand .navbar-link:hover, +.navbar.is-light .navbar-brand .navbar-link.is-active { + background-color: #e8e8e8; + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-light .navbar-brand .navbar-link::after { + border-color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-light .navbar-burger { + color: rgba(0, 0, 0, 0.7); +} + +@media screen and (min-width: 1024px) { + .navbar.is-light .navbar-start > .navbar-item, + .navbar.is-light .navbar-start .navbar-link, + .navbar.is-light .navbar-end > .navbar-item, + .navbar.is-light .navbar-end .navbar-link { + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-light .navbar-start > a.navbar-item:focus, .navbar.is-light .navbar-start > a.navbar-item:hover, .navbar.is-light .navbar-start > a.navbar-item.is-active, + .navbar.is-light .navbar-start .navbar-link:focus, + .navbar.is-light .navbar-start .navbar-link:hover, + .navbar.is-light .navbar-start .navbar-link.is-active, + .navbar.is-light .navbar-end > a.navbar-item:focus, + .navbar.is-light .navbar-end > a.navbar-item:hover, + .navbar.is-light .navbar-end > a.navbar-item.is-active, + .navbar.is-light .navbar-end .navbar-link:focus, + .navbar.is-light .navbar-end .navbar-link:hover, + .navbar.is-light .navbar-end .navbar-link.is-active { + background-color: #e8e8e8; + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-light .navbar-start .navbar-link::after, + .navbar.is-light .navbar-end .navbar-link::after { + border-color: rgba(0, 0, 0, 0.7); + } + .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #e8e8e8; + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-light .navbar-dropdown a.navbar-item.is-active { + background-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); + } +} + +.navbar.is-dark { + background-color: #363636; + color: #fff; +} + +.navbar.is-dark .navbar-brand > .navbar-item, +.navbar.is-dark .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-dark .navbar-brand > a.navbar-item:focus, .navbar.is-dark .navbar-brand > a.navbar-item:hover, .navbar.is-dark .navbar-brand > a.navbar-item.is-active, +.navbar.is-dark .navbar-brand .navbar-link:focus, +.navbar.is-dark .navbar-brand .navbar-link:hover, +.navbar.is-dark .navbar-brand .navbar-link.is-active { + background-color: #292929; + color: #fff; +} + +.navbar.is-dark .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-dark .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-dark .navbar-start > .navbar-item, + .navbar.is-dark .navbar-start .navbar-link, + .navbar.is-dark .navbar-end > .navbar-item, + .navbar.is-dark .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-dark .navbar-start > a.navbar-item:focus, .navbar.is-dark .navbar-start > a.navbar-item:hover, .navbar.is-dark .navbar-start > a.navbar-item.is-active, + .navbar.is-dark .navbar-start .navbar-link:focus, + .navbar.is-dark .navbar-start .navbar-link:hover, + .navbar.is-dark .navbar-start .navbar-link.is-active, + .navbar.is-dark .navbar-end > a.navbar-item:focus, + .navbar.is-dark .navbar-end > a.navbar-item:hover, + .navbar.is-dark .navbar-end > a.navbar-item.is-active, + .navbar.is-dark .navbar-end .navbar-link:focus, + .navbar.is-dark .navbar-end .navbar-link:hover, + .navbar.is-dark .navbar-end .navbar-link.is-active { + background-color: #292929; + color: #fff; + } + .navbar.is-dark .navbar-start .navbar-link::after, + .navbar.is-dark .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #292929; + color: #fff; + } + .navbar.is-dark .navbar-dropdown a.navbar-item.is-active { + background-color: #363636; + color: #fff; + } +} + +.navbar.is-primary { + background-color: #00d1b2; + color: #fff; +} + +.navbar.is-primary .navbar-brand > .navbar-item, +.navbar.is-primary .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-primary .navbar-brand > a.navbar-item:focus, .navbar.is-primary .navbar-brand > a.navbar-item:hover, .navbar.is-primary .navbar-brand > a.navbar-item.is-active, +.navbar.is-primary .navbar-brand .navbar-link:focus, +.navbar.is-primary .navbar-brand .navbar-link:hover, +.navbar.is-primary .navbar-brand .navbar-link.is-active { + background-color: #00b89c; + color: #fff; +} + +.navbar.is-primary .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-primary .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-primary .navbar-start > .navbar-item, + .navbar.is-primary .navbar-start .navbar-link, + .navbar.is-primary .navbar-end > .navbar-item, + .navbar.is-primary .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-primary .navbar-start > a.navbar-item:focus, .navbar.is-primary .navbar-start > a.navbar-item:hover, .navbar.is-primary .navbar-start > a.navbar-item.is-active, + .navbar.is-primary .navbar-start .navbar-link:focus, + .navbar.is-primary .navbar-start .navbar-link:hover, + .navbar.is-primary .navbar-start .navbar-link.is-active, + .navbar.is-primary .navbar-end > a.navbar-item:focus, + .navbar.is-primary .navbar-end > a.navbar-item:hover, + .navbar.is-primary .navbar-end > a.navbar-item.is-active, + .navbar.is-primary .navbar-end .navbar-link:focus, + .navbar.is-primary .navbar-end .navbar-link:hover, + .navbar.is-primary .navbar-end .navbar-link.is-active { + background-color: #00b89c; + color: #fff; + } + .navbar.is-primary .navbar-start .navbar-link::after, + .navbar.is-primary .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #00b89c; + color: #fff; + } + .navbar.is-primary .navbar-dropdown a.navbar-item.is-active { + background-color: #00d1b2; + color: #fff; + } +} + +.navbar.is-link { + background-color: #3273dc; + color: #fff; +} + +.navbar.is-link .navbar-brand > .navbar-item, +.navbar.is-link .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-link .navbar-brand > a.navbar-item:focus, .navbar.is-link .navbar-brand > a.navbar-item:hover, .navbar.is-link .navbar-brand > a.navbar-item.is-active, +.navbar.is-link .navbar-brand .navbar-link:focus, +.navbar.is-link .navbar-brand .navbar-link:hover, +.navbar.is-link .navbar-brand .navbar-link.is-active { + background-color: #2366d1; + color: #fff; +} + +.navbar.is-link .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-link .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-link .navbar-start > .navbar-item, + .navbar.is-link .navbar-start .navbar-link, + .navbar.is-link .navbar-end > .navbar-item, + .navbar.is-link .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-link .navbar-start > a.navbar-item:focus, .navbar.is-link .navbar-start > a.navbar-item:hover, .navbar.is-link .navbar-start > a.navbar-item.is-active, + .navbar.is-link .navbar-start .navbar-link:focus, + .navbar.is-link .navbar-start .navbar-link:hover, + .navbar.is-link .navbar-start .navbar-link.is-active, + .navbar.is-link .navbar-end > a.navbar-item:focus, + .navbar.is-link .navbar-end > a.navbar-item:hover, + .navbar.is-link .navbar-end > a.navbar-item.is-active, + .navbar.is-link .navbar-end .navbar-link:focus, + .navbar.is-link .navbar-end .navbar-link:hover, + .navbar.is-link .navbar-end .navbar-link.is-active { + background-color: #2366d1; + color: #fff; + } + .navbar.is-link .navbar-start .navbar-link::after, + .navbar.is-link .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #2366d1; + color: #fff; + } + .navbar.is-link .navbar-dropdown a.navbar-item.is-active { + background-color: #3273dc; + color: #fff; + } +} + +.navbar.is-info { + background-color: #3298dc; + color: #fff; +} + +.navbar.is-info .navbar-brand > .navbar-item, +.navbar.is-info .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-info .navbar-brand > a.navbar-item:focus, .navbar.is-info .navbar-brand > a.navbar-item:hover, .navbar.is-info .navbar-brand > a.navbar-item.is-active, +.navbar.is-info .navbar-brand .navbar-link:focus, +.navbar.is-info .navbar-brand .navbar-link:hover, +.navbar.is-info .navbar-brand .navbar-link.is-active { + background-color: #238cd1; + color: #fff; +} + +.navbar.is-info .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-info .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-info .navbar-start > .navbar-item, + .navbar.is-info .navbar-start .navbar-link, + .navbar.is-info .navbar-end > .navbar-item, + .navbar.is-info .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-info .navbar-start > a.navbar-item:focus, .navbar.is-info .navbar-start > a.navbar-item:hover, .navbar.is-info .navbar-start > a.navbar-item.is-active, + .navbar.is-info .navbar-start .navbar-link:focus, + .navbar.is-info .navbar-start .navbar-link:hover, + .navbar.is-info .navbar-start .navbar-link.is-active, + .navbar.is-info .navbar-end > a.navbar-item:focus, + .navbar.is-info .navbar-end > a.navbar-item:hover, + .navbar.is-info .navbar-end > a.navbar-item.is-active, + .navbar.is-info .navbar-end .navbar-link:focus, + .navbar.is-info .navbar-end .navbar-link:hover, + .navbar.is-info .navbar-end .navbar-link.is-active { + background-color: #238cd1; + color: #fff; + } + .navbar.is-info .navbar-start .navbar-link::after, + .navbar.is-info .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #238cd1; + color: #fff; + } + .navbar.is-info .navbar-dropdown a.navbar-item.is-active { + background-color: #3298dc; + color: #fff; + } +} + +.navbar.is-success { + background-color: #48c774; + color: #fff; +} + +.navbar.is-success .navbar-brand > .navbar-item, +.navbar.is-success .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-success .navbar-brand > a.navbar-item:focus, .navbar.is-success .navbar-brand > a.navbar-item:hover, .navbar.is-success .navbar-brand > a.navbar-item.is-active, +.navbar.is-success .navbar-brand .navbar-link:focus, +.navbar.is-success .navbar-brand .navbar-link:hover, +.navbar.is-success .navbar-brand .navbar-link.is-active { + background-color: #3abb67; + color: #fff; +} + +.navbar.is-success .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-success .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-success .navbar-start > .navbar-item, + .navbar.is-success .navbar-start .navbar-link, + .navbar.is-success .navbar-end > .navbar-item, + .navbar.is-success .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-success .navbar-start > a.navbar-item:focus, .navbar.is-success .navbar-start > a.navbar-item:hover, .navbar.is-success .navbar-start > a.navbar-item.is-active, + .navbar.is-success .navbar-start .navbar-link:focus, + .navbar.is-success .navbar-start .navbar-link:hover, + .navbar.is-success .navbar-start .navbar-link.is-active, + .navbar.is-success .navbar-end > a.navbar-item:focus, + .navbar.is-success .navbar-end > a.navbar-item:hover, + .navbar.is-success .navbar-end > a.navbar-item.is-active, + .navbar.is-success .navbar-end .navbar-link:focus, + .navbar.is-success .navbar-end .navbar-link:hover, + .navbar.is-success .navbar-end .navbar-link.is-active { + background-color: #3abb67; + color: #fff; + } + .navbar.is-success .navbar-start .navbar-link::after, + .navbar.is-success .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #3abb67; + color: #fff; + } + .navbar.is-success .navbar-dropdown a.navbar-item.is-active { + background-color: #48c774; + color: #fff; + } +} + +.navbar.is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-brand > .navbar-item, +.navbar.is-warning .navbar-brand .navbar-link { + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-brand > a.navbar-item:focus, .navbar.is-warning .navbar-brand > a.navbar-item:hover, .navbar.is-warning .navbar-brand > a.navbar-item.is-active, +.navbar.is-warning .navbar-brand .navbar-link:focus, +.navbar.is-warning .navbar-brand .navbar-link:hover, +.navbar.is-warning .navbar-brand .navbar-link.is-active { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-brand .navbar-link::after { + border-color: rgba(0, 0, 0, 0.7); +} + +.navbar.is-warning .navbar-burger { + color: rgba(0, 0, 0, 0.7); +} + +@media screen and (min-width: 1024px) { + .navbar.is-warning .navbar-start > .navbar-item, + .navbar.is-warning .navbar-start .navbar-link, + .navbar.is-warning .navbar-end > .navbar-item, + .navbar.is-warning .navbar-end .navbar-link { + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-start > a.navbar-item:focus, .navbar.is-warning .navbar-start > a.navbar-item:hover, .navbar.is-warning .navbar-start > a.navbar-item.is-active, + .navbar.is-warning .navbar-start .navbar-link:focus, + .navbar.is-warning .navbar-start .navbar-link:hover, + .navbar.is-warning .navbar-start .navbar-link.is-active, + .navbar.is-warning .navbar-end > a.navbar-item:focus, + .navbar.is-warning .navbar-end > a.navbar-item:hover, + .navbar.is-warning .navbar-end > a.navbar-item.is-active, + .navbar.is-warning .navbar-end .navbar-link:focus, + .navbar.is-warning .navbar-end .navbar-link:hover, + .navbar.is-warning .navbar-end .navbar-link.is-active { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-start .navbar-link::after, + .navbar.is-warning .navbar-end .navbar-link::after { + border-color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); + } + .navbar.is-warning .navbar-dropdown a.navbar-item.is-active { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); + } +} + +.navbar.is-danger { + background-color: #f14668; + color: #fff; +} + +.navbar.is-danger .navbar-brand > .navbar-item, +.navbar.is-danger .navbar-brand .navbar-link { + color: #fff; +} + +.navbar.is-danger .navbar-brand > a.navbar-item:focus, .navbar.is-danger .navbar-brand > a.navbar-item:hover, .navbar.is-danger .navbar-brand > a.navbar-item.is-active, +.navbar.is-danger .navbar-brand .navbar-link:focus, +.navbar.is-danger .navbar-brand .navbar-link:hover, +.navbar.is-danger .navbar-brand .navbar-link.is-active { + background-color: #ef2e55; + color: #fff; +} + +.navbar.is-danger .navbar-brand .navbar-link::after { + border-color: #fff; +} + +.navbar.is-danger .navbar-burger { + color: #fff; +} + +@media screen and (min-width: 1024px) { + .navbar.is-danger .navbar-start > .navbar-item, + .navbar.is-danger .navbar-start .navbar-link, + .navbar.is-danger .navbar-end > .navbar-item, + .navbar.is-danger .navbar-end .navbar-link { + color: #fff; + } + .navbar.is-danger .navbar-start > a.navbar-item:focus, .navbar.is-danger .navbar-start > a.navbar-item:hover, .navbar.is-danger .navbar-start > a.navbar-item.is-active, + .navbar.is-danger .navbar-start .navbar-link:focus, + .navbar.is-danger .navbar-start .navbar-link:hover, + .navbar.is-danger .navbar-start .navbar-link.is-active, + .navbar.is-danger .navbar-end > a.navbar-item:focus, + .navbar.is-danger .navbar-end > a.navbar-item:hover, + .navbar.is-danger .navbar-end > a.navbar-item.is-active, + .navbar.is-danger .navbar-end .navbar-link:focus, + .navbar.is-danger .navbar-end .navbar-link:hover, + .navbar.is-danger .navbar-end .navbar-link.is-active { + background-color: #ef2e55; + color: #fff; + } + .navbar.is-danger .navbar-start .navbar-link::after, + .navbar.is-danger .navbar-end .navbar-link::after { + border-color: #fff; + } + .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link, + .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link, + .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #ef2e55; + color: #fff; + } + .navbar.is-danger .navbar-dropdown a.navbar-item.is-active { + background-color: #f14668; + color: #fff; + } +} + +.navbar > .container { + align-items: stretch; + display: flex; + min-height: 3.25rem; + width: 100%; +} + +.navbar.has-shadow { + box-shadow: 0 2px 0 0 whitesmoke; +} + +.navbar.is-fixed-bottom, .navbar.is-fixed-top { + left: 0; + position: fixed; + right: 0; + z-index: 30; +} + +.navbar.is-fixed-bottom { + bottom: 0; +} + +.navbar.is-fixed-bottom.has-shadow { + box-shadow: 0 -2px 0 0 whitesmoke; +} + +.navbar.is-fixed-top { + top: 0; +} + +html.has-navbar-fixed-top, +body.has-navbar-fixed-top { + padding-top: 3.25rem; +} + +html.has-navbar-fixed-bottom, +body.has-navbar-fixed-bottom { + padding-bottom: 3.25rem; +} + +.navbar-brand, +.navbar-tabs { + align-items: stretch; + display: flex; + flex-shrink: 0; + min-height: 3.25rem; +} + +.navbar-brand a.navbar-item:focus, .navbar-brand a.navbar-item:hover { + background-color: transparent; +} + +.navbar-tabs { + -webkit-overflow-scrolling: touch; + max-width: 100vw; + overflow-x: auto; + overflow-y: hidden; +} + +.navbar-burger { + color: #4a4a4a; + cursor: pointer; + display: block; + height: 3.25rem; + position: relative; + width: 3.25rem; + margin-left: auto; +} + +.navbar-burger span { + background-color: currentColor; + display: block; + height: 1px; + left: calc(50% - 8px); + position: absolute; + transform-origin: center; + transition-duration: 86ms; + transition-property: background-color, opacity, transform; + transition-timing-function: ease-out; + width: 16px; +} + +.navbar-burger span:nth-child(1) { + top: calc(50% - 6px); +} + +.navbar-burger span:nth-child(2) { + top: calc(50% - 1px); +} + +.navbar-burger span:nth-child(3) { + top: calc(50% + 4px); +} + +.navbar-burger:hover { + background-color: rgba(0, 0, 0, 0.05); +} + +.navbar-burger.is-active span:nth-child(1) { + transform: translateY(5px) rotate(45deg); +} + +.navbar-burger.is-active span:nth-child(2) { + opacity: 0; +} + +.navbar-burger.is-active span:nth-child(3) { + transform: translateY(-5px) rotate(-45deg); +} + +.navbar-menu { + display: none; +} + +.navbar-item, +.navbar-link { + color: #4a4a4a; + display: block; + line-height: 1.5; + padding: 0.5rem 0.75rem; + position: relative; +} + +.navbar-item .icon:only-child, +.navbar-link .icon:only-child { + margin-left: -0.25rem; + margin-right: -0.25rem; +} + +a.navbar-item, +.navbar-link { + cursor: pointer; +} + +a.navbar-item:focus, a.navbar-item:focus-within, a.navbar-item:hover, a.navbar-item.is-active, +.navbar-link:focus, +.navbar-link:focus-within, +.navbar-link:hover, +.navbar-link.is-active { + background-color: #fafafa; + color: #3273dc; +} + +.navbar-item { + flex-grow: 0; + flex-shrink: 0; +} + +.navbar-item img { + max-height: 1.75rem; +} + +.navbar-item.has-dropdown { + padding: 0; +} + +.navbar-item.is-expanded { + flex-grow: 1; + flex-shrink: 1; +} + +.navbar-item.is-tab { + border-bottom: 1px solid transparent; + min-height: 3.25rem; + padding-bottom: calc(0.5rem - 1px); +} + +.navbar-item.is-tab:focus, .navbar-item.is-tab:hover { + background-color: transparent; + border-bottom-color: #3273dc; +} + +.navbar-item.is-tab.is-active { + background-color: transparent; + border-bottom-color: #3273dc; + border-bottom-style: solid; + border-bottom-width: 3px; + color: #3273dc; + padding-bottom: calc(0.5rem - 3px); +} + +.navbar-content { + flex-grow: 1; + flex-shrink: 1; +} + +.navbar-link:not(.is-arrowless) { + padding-right: 2.5em; +} + +.navbar-link:not(.is-arrowless)::after { + border-color: #3273dc; + margin-top: -0.375em; + right: 1.125em; +} + +.navbar-dropdown { + font-size: 0.875rem; + padding-bottom: 0.5rem; + padding-top: 0.5rem; +} + +.navbar-dropdown .navbar-item { + padding-left: 1.5rem; + padding-right: 1.5rem; +} + +.navbar-divider { + background-color: whitesmoke; + border: none; + display: none; + height: 2px; + margin: 0.5rem 0; +} + +@media screen and (max-width: 1023px) { + .navbar > .container { + display: block; + } + .navbar-brand .navbar-item, + .navbar-tabs .navbar-item { + align-items: center; + display: flex; + } + .navbar-link::after { + display: none; + } + .navbar-menu { + background-color: white; + box-shadow: 0 8px 16px rgba(10, 10, 10, 0.1); + padding: 0.5rem 0; + } + .navbar-menu.is-active { + display: block; + } + .navbar.is-fixed-bottom-touch, .navbar.is-fixed-top-touch { + left: 0; + position: fixed; + right: 0; + z-index: 30; + } + .navbar.is-fixed-bottom-touch { + bottom: 0; + } + .navbar.is-fixed-bottom-touch.has-shadow { + box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1); + } + .navbar.is-fixed-top-touch { + top: 0; + } + .navbar.is-fixed-top .navbar-menu, .navbar.is-fixed-top-touch .navbar-menu { + -webkit-overflow-scrolling: touch; + max-height: calc(100vh - 3.25rem); + overflow: auto; + } + html.has-navbar-fixed-top-touch, + body.has-navbar-fixed-top-touch { + padding-top: 3.25rem; + } + html.has-navbar-fixed-bottom-touch, + body.has-navbar-fixed-bottom-touch { + padding-bottom: 3.25rem; + } +} + +@media screen and (min-width: 1024px) { + .navbar, + .navbar-menu, + .navbar-start, + .navbar-end { + align-items: stretch; + display: flex; + } + .navbar { + min-height: 3.25rem; + } + .navbar.is-spaced { + padding: 1rem 2rem; + } + .navbar.is-spaced .navbar-start, + .navbar.is-spaced .navbar-end { + align-items: center; + } + .navbar.is-spaced a.navbar-item, + .navbar.is-spaced .navbar-link { + border-radius: 4px; + } + .navbar.is-transparent a.navbar-item:focus, .navbar.is-transparent a.navbar-item:hover, .navbar.is-transparent a.navbar-item.is-active, + .navbar.is-transparent .navbar-link:focus, + .navbar.is-transparent .navbar-link:hover, + .navbar.is-transparent .navbar-link.is-active { + background-color: transparent !important; + } + .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link, .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link { + background-color: transparent !important; + } + .navbar.is-transparent .navbar-dropdown a.navbar-item:focus, .navbar.is-transparent .navbar-dropdown a.navbar-item:hover { + background-color: whitesmoke; + color: #0a0a0a; + } + .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active { + background-color: whitesmoke; + color: #3273dc; + } + .navbar-burger { + display: none; + } + .navbar-item, + .navbar-link { + align-items: center; + display: flex; + } + .navbar-item.has-dropdown { + align-items: stretch; + } + .navbar-item.has-dropdown-up .navbar-link::after { + transform: rotate(135deg) translate(0.25em, -0.25em); + } + .navbar-item.has-dropdown-up .navbar-dropdown { + border-bottom: 2px solid #dbdbdb; + border-radius: 6px 6px 0 0; + border-top: none; + bottom: 100%; + box-shadow: 0 -8px 8px rgba(10, 10, 10, 0.1); + top: auto; + } + .navbar-item.is-active .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown { + display: block; + } + .navbar.is-spaced .navbar-item.is-active .navbar-dropdown, .navbar-item.is-active .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown, .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown, .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed, .navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown, .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed { + opacity: 1; + pointer-events: auto; + transform: translateY(0); + } + .navbar-menu { + flex-grow: 1; + flex-shrink: 0; + } + .navbar-start { + justify-content: flex-start; + margin-right: auto; + } + .navbar-end { + justify-content: flex-end; + margin-left: auto; + } + .navbar-dropdown { + background-color: white; + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + border-top: 2px solid #dbdbdb; + box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1); + display: none; + font-size: 0.875rem; + left: 0; + min-width: 100%; + position: absolute; + top: 100%; + z-index: 20; + } + .navbar-dropdown .navbar-item { + padding: 0.375rem 1rem; + white-space: nowrap; + } + .navbar-dropdown a.navbar-item { + padding-right: 3rem; + } + .navbar-dropdown a.navbar-item:focus, .navbar-dropdown a.navbar-item:hover { + background-color: whitesmoke; + color: #0a0a0a; + } + .navbar-dropdown a.navbar-item.is-active { + background-color: whitesmoke; + color: #3273dc; + } + .navbar.is-spaced .navbar-dropdown, .navbar-dropdown.is-boxed { + border-radius: 6px; + border-top: none; + box-shadow: 0 8px 8px rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.1); + display: block; + opacity: 0; + pointer-events: none; + top: calc(100% + (-4px)); + transform: translateY(-5px); + transition-duration: 86ms; + transition-property: opacity, transform; + } + .navbar-dropdown.is-right { + left: auto; + right: 0; + } + .navbar-divider { + display: block; + } + .navbar > .container .navbar-brand, + .container > .navbar .navbar-brand { + margin-left: -0.75rem; + } + .navbar > .container .navbar-menu, + .container > .navbar .navbar-menu { + margin-right: -0.75rem; + } + .navbar.is-fixed-bottom-desktop, .navbar.is-fixed-top-desktop { + left: 0; + position: fixed; + right: 0; + z-index: 30; + } + .navbar.is-fixed-bottom-desktop { + bottom: 0; + } + .navbar.is-fixed-bottom-desktop.has-shadow { + box-shadow: 0 -2px 3px rgba(10, 10, 10, 0.1); + } + .navbar.is-fixed-top-desktop { + top: 0; + } + html.has-navbar-fixed-top-desktop, + body.has-navbar-fixed-top-desktop { + padding-top: 3.25rem; + } + html.has-navbar-fixed-bottom-desktop, + body.has-navbar-fixed-bottom-desktop { + padding-bottom: 3.25rem; + } + html.has-spaced-navbar-fixed-top, + body.has-spaced-navbar-fixed-top { + padding-top: 5.25rem; + } + html.has-spaced-navbar-fixed-bottom, + body.has-spaced-navbar-fixed-bottom { + padding-bottom: 5.25rem; + } + a.navbar-item.is-active, + .navbar-link.is-active { + color: #0a0a0a; + } + a.navbar-item.is-active:not(:focus):not(:hover), + .navbar-link.is-active:not(:focus):not(:hover) { + background-color: transparent; + } + .navbar-item.has-dropdown:focus .navbar-link, .navbar-item.has-dropdown:hover .navbar-link, .navbar-item.has-dropdown.is-active .navbar-link { + background-color: #fafafa; + } +} + +.hero.is-fullheight-with-navbar { + min-height: calc(100vh - 3.25rem); +} + +.pagination { + font-size: 1rem; + margin: -0.25rem; +} + +.pagination.is-small { + font-size: 0.75rem; +} + +.pagination.is-medium { + font-size: 1.25rem; +} + +.pagination.is-large { + font-size: 1.5rem; +} + +.pagination.is-rounded .pagination-previous, +.pagination.is-rounded .pagination-next { + padding-left: 1em; + padding-right: 1em; + border-radius: 290486px; +} + +.pagination.is-rounded .pagination-link { + border-radius: 290486px; +} + +.pagination, +.pagination-list { + align-items: center; + display: flex; + justify-content: center; + text-align: center; +} + +.pagination-previous, +.pagination-next, +.pagination-link, +.pagination-ellipsis { + font-size: 1em; + justify-content: center; + margin: 0.25rem; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: center; +} + +.pagination-previous, +.pagination-next, +.pagination-link { + border-color: #dbdbdb; + color: #363636; + min-width: 2.5em; +} + +.pagination-previous:hover, +.pagination-next:hover, +.pagination-link:hover { + border-color: #b5b5b5; + color: #363636; +} + +.pagination-previous:focus, +.pagination-next:focus, +.pagination-link:focus { + border-color: #3273dc; +} + +.pagination-previous:active, +.pagination-next:active, +.pagination-link:active { + box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.2); +} + +.pagination-previous[disabled], +.pagination-next[disabled], +.pagination-link[disabled] { + background-color: #dbdbdb; + border-color: #dbdbdb; + box-shadow: none; + color: #7a7a7a; + opacity: 0.5; +} + +.pagination-previous, +.pagination-next { + padding-left: 0.75em; + padding-right: 0.75em; + white-space: nowrap; +} + +.pagination-link.is-current { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; +} + +.pagination-ellipsis { + color: #b5b5b5; + pointer-events: none; +} + +.pagination-list { + flex-wrap: wrap; +} + +@media screen and (max-width: 768px) { + .pagination { + flex-wrap: wrap; + } + .pagination-previous, + .pagination-next { + flex-grow: 1; + flex-shrink: 1; + } + .pagination-list li { + flex-grow: 1; + flex-shrink: 1; + } +} + +@media screen and (min-width: 769px), print { + .pagination-list { + flex-grow: 1; + flex-shrink: 1; + justify-content: flex-start; + order: 1; + } + .pagination-previous { + order: 2; + } + .pagination-next { + order: 3; + } + .pagination { + justify-content: space-between; + } + .pagination.is-centered .pagination-previous { + order: 1; + } + .pagination.is-centered .pagination-list { + justify-content: center; + order: 2; + } + .pagination.is-centered .pagination-next { + order: 3; + } + .pagination.is-right .pagination-previous { + order: 1; + } + .pagination.is-right .pagination-next { + order: 2; + } + .pagination.is-right .pagination-list { + justify-content: flex-end; + order: 3; + } +} + +.panel { + border-radius: 6px; + box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0px 0 1px rgba(10, 10, 10, 0.02); + font-size: 1rem; +} + +.panel:not(:last-child) { + margin-bottom: 1.5rem; +} + +.panel.is-white .panel-heading { + background-color: white; + color: #0a0a0a; +} + +.panel.is-white .panel-tabs a.is-active { + border-bottom-color: white; +} + +.panel.is-white .panel-block.is-active .panel-icon { + color: white; +} + +.panel.is-black .panel-heading { + background-color: #0a0a0a; + color: white; +} + +.panel.is-black .panel-tabs a.is-active { + border-bottom-color: #0a0a0a; +} + +.panel.is-black .panel-block.is-active .panel-icon { + color: #0a0a0a; +} + +.panel.is-light .panel-heading { + background-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.panel.is-light .panel-tabs a.is-active { + border-bottom-color: whitesmoke; +} + +.panel.is-light .panel-block.is-active .panel-icon { + color: whitesmoke; +} + +.panel.is-dark .panel-heading { + background-color: #363636; + color: #fff; +} + +.panel.is-dark .panel-tabs a.is-active { + border-bottom-color: #363636; +} + +.panel.is-dark .panel-block.is-active .panel-icon { + color: #363636; +} + +.panel.is-primary .panel-heading { + background-color: #00d1b2; + color: #fff; +} + +.panel.is-primary .panel-tabs a.is-active { + border-bottom-color: #00d1b2; +} + +.panel.is-primary .panel-block.is-active .panel-icon { + color: #00d1b2; +} + +.panel.is-link .panel-heading { + background-color: #3273dc; + color: #fff; +} + +.panel.is-link .panel-tabs a.is-active { + border-bottom-color: #3273dc; +} + +.panel.is-link .panel-block.is-active .panel-icon { + color: #3273dc; +} + +.panel.is-info .panel-heading { + background-color: #3298dc; + color: #fff; +} + +.panel.is-info .panel-tabs a.is-active { + border-bottom-color: #3298dc; +} + +.panel.is-info .panel-block.is-active .panel-icon { + color: #3298dc; +} + +.panel.is-success .panel-heading { + background-color: #48c774; + color: #fff; +} + +.panel.is-success .panel-tabs a.is-active { + border-bottom-color: #48c774; +} + +.panel.is-success .panel-block.is-active .panel-icon { + color: #48c774; +} + +.panel.is-warning .panel-heading { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.panel.is-warning .panel-tabs a.is-active { + border-bottom-color: #ffdd57; +} + +.panel.is-warning .panel-block.is-active .panel-icon { + color: #ffdd57; +} + +.panel.is-danger .panel-heading { + background-color: #f14668; + color: #fff; +} + +.panel.is-danger .panel-tabs a.is-active { + border-bottom-color: #f14668; +} + +.panel.is-danger .panel-block.is-active .panel-icon { + color: #f14668; +} + +.panel-tabs:not(:last-child), +.panel-block:not(:last-child) { + border-bottom: 1px solid #ededed; +} + +.panel-heading { + background-color: #ededed; + border-radius: 6px 6px 0 0; + color: #363636; + font-size: 1.25em; + font-weight: 700; + line-height: 1.25; + padding: 0.75em 1em; +} + +.panel-tabs { + align-items: flex-end; + display: flex; + font-size: 0.875em; + justify-content: center; +} + +.panel-tabs a { + border-bottom: 1px solid #dbdbdb; + margin-bottom: -1px; + padding: 0.5em; +} + +.panel-tabs a.is-active { + border-bottom-color: #4a4a4a; + color: #363636; +} + +.panel-list a { + color: #4a4a4a; +} + +.panel-list a:hover { + color: #3273dc; +} + +.panel-block { + align-items: center; + color: #363636; + display: flex; + justify-content: flex-start; + padding: 0.5em 0.75em; +} + +.panel-block input[type="checkbox"] { + margin-right: 0.75em; +} + +.panel-block > .control { + flex-grow: 1; + flex-shrink: 1; + width: 100%; +} + +.panel-block.is-wrapped { + flex-wrap: wrap; +} + +.panel-block.is-active { + border-left-color: #3273dc; + color: #363636; +} + +.panel-block.is-active .panel-icon { + color: #3273dc; +} + +.panel-block:last-child { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; +} + +a.panel-block, +label.panel-block { + cursor: pointer; +} + +a.panel-block:hover, +label.panel-block:hover { + background-color: whitesmoke; +} + +.panel-icon { + display: inline-block; + font-size: 14px; + height: 1em; + line-height: 1em; + text-align: center; + vertical-align: top; + width: 1em; + color: #7a7a7a; + margin-right: 0.75em; +} + +.panel-icon .fa { + font-size: inherit; + line-height: inherit; +} + +.tabs { + -webkit-overflow-scrolling: touch; + align-items: stretch; + display: flex; + font-size: 1rem; + justify-content: space-between; + overflow: hidden; + overflow-x: auto; + white-space: nowrap; +} + +.tabs a { + align-items: center; + border-bottom-color: #dbdbdb; + border-bottom-style: solid; + border-bottom-width: 1px; + color: #4a4a4a; + display: flex; + justify-content: center; + margin-bottom: -1px; + padding: 0.5em 1em; + vertical-align: top; +} + +.tabs a:hover { + border-bottom-color: #363636; + color: #363636; +} + +.tabs li { + display: block; +} + +.tabs li.is-active a { + border-bottom-color: #3273dc; + color: #3273dc; +} + +.tabs ul { + align-items: center; + border-bottom-color: #dbdbdb; + border-bottom-style: solid; + border-bottom-width: 1px; + display: flex; + flex-grow: 1; + flex-shrink: 0; + justify-content: flex-start; +} + +.tabs ul.is-left { + padding-right: 0.75em; +} + +.tabs ul.is-center { + flex: none; + justify-content: center; + padding-left: 0.75em; + padding-right: 0.75em; +} + +.tabs ul.is-right { + justify-content: flex-end; + padding-left: 0.75em; +} + +.tabs .icon:first-child { + margin-right: 0.5em; +} + +.tabs .icon:last-child { + margin-left: 0.5em; +} + +.tabs.is-centered ul { + justify-content: center; +} + +.tabs.is-right ul { + justify-content: flex-end; +} + +.tabs.is-boxed a { + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} + +.tabs.is-boxed a:hover { + background-color: whitesmoke; + border-bottom-color: #dbdbdb; +} + +.tabs.is-boxed li.is-active a { + background-color: white; + border-color: #dbdbdb; + border-bottom-color: transparent !important; +} + +.tabs.is-fullwidth li { + flex-grow: 1; + flex-shrink: 0; +} + +.tabs.is-toggle a { + border-color: #dbdbdb; + border-style: solid; + border-width: 1px; + margin-bottom: 0; + position: relative; +} + +.tabs.is-toggle a:hover { + background-color: whitesmoke; + border-color: #b5b5b5; + z-index: 2; +} + +.tabs.is-toggle li + li { + margin-left: -1px; +} + +.tabs.is-toggle li:first-child a { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} + +.tabs.is-toggle li:last-child a { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.tabs.is-toggle li.is-active a { + background-color: #3273dc; + border-color: #3273dc; + color: #fff; + z-index: 1; +} + +.tabs.is-toggle ul { + border-bottom: none; +} + +.tabs.is-toggle.is-toggle-rounded li:first-child a { + border-bottom-left-radius: 290486px; + border-top-left-radius: 290486px; + padding-left: 1.25em; +} + +.tabs.is-toggle.is-toggle-rounded li:last-child a { + border-bottom-right-radius: 290486px; + border-top-right-radius: 290486px; + padding-right: 1.25em; +} + +.tabs.is-small { + font-size: 0.75rem; +} + +.tabs.is-medium { + font-size: 1.25rem; +} + +.tabs.is-large { + font-size: 1.5rem; +} + +.column { + display: block; + flex-basis: 0; + flex-grow: 1; + flex-shrink: 1; + padding: 0.75rem; +} + +.columns.is-mobile > .column.is-narrow { + flex: none; +} + +.columns.is-mobile > .column.is-full { + flex: none; + width: 100%; +} + +.columns.is-mobile > .column.is-three-quarters { + flex: none; + width: 75%; +} + +.columns.is-mobile > .column.is-two-thirds { + flex: none; + width: 66.6666%; +} + +.columns.is-mobile > .column.is-half { + flex: none; + width: 50%; +} + +.columns.is-mobile > .column.is-one-third { + flex: none; + width: 33.3333%; +} + +.columns.is-mobile > .column.is-one-quarter { + flex: none; + width: 25%; +} + +.columns.is-mobile > .column.is-one-fifth { + flex: none; + width: 20%; +} + +.columns.is-mobile > .column.is-two-fifths { + flex: none; + width: 40%; +} + +.columns.is-mobile > .column.is-three-fifths { + flex: none; + width: 60%; +} + +.columns.is-mobile > .column.is-four-fifths { + flex: none; + width: 80%; +} + +.columns.is-mobile > .column.is-offset-three-quarters { + margin-left: 75%; +} + +.columns.is-mobile > .column.is-offset-two-thirds { + margin-left: 66.6666%; +} + +.columns.is-mobile > .column.is-offset-half { + margin-left: 50%; +} + +.columns.is-mobile > .column.is-offset-one-third { + margin-left: 33.3333%; +} + +.columns.is-mobile > .column.is-offset-one-quarter { + margin-left: 25%; +} + +.columns.is-mobile > .column.is-offset-one-fifth { + margin-left: 20%; +} + +.columns.is-mobile > .column.is-offset-two-fifths { + margin-left: 40%; +} + +.columns.is-mobile > .column.is-offset-three-fifths { + margin-left: 60%; +} + +.columns.is-mobile > .column.is-offset-four-fifths { + margin-left: 80%; +} + +.columns.is-mobile > .column.is-0 { + flex: none; + width: 0%; +} + +.columns.is-mobile > .column.is-offset-0 { + margin-left: 0%; +} + +.columns.is-mobile > .column.is-1 { + flex: none; + width: 8.33333%; +} + +.columns.is-mobile > .column.is-offset-1 { + margin-left: 8.33333%; +} + +.columns.is-mobile > .column.is-2 { + flex: none; + width: 16.66667%; +} + +.columns.is-mobile > .column.is-offset-2 { + margin-left: 16.66667%; +} + +.columns.is-mobile > .column.is-3 { + flex: none; + width: 25%; +} + +.columns.is-mobile > .column.is-offset-3 { + margin-left: 25%; +} + +.columns.is-mobile > .column.is-4 { + flex: none; + width: 33.33333%; +} + +.columns.is-mobile > .column.is-offset-4 { + margin-left: 33.33333%; +} + +.columns.is-mobile > .column.is-5 { + flex: none; + width: 41.66667%; +} + +.columns.is-mobile > .column.is-offset-5 { + margin-left: 41.66667%; +} + +.columns.is-mobile > .column.is-6 { + flex: none; + width: 50%; +} + +.columns.is-mobile > .column.is-offset-6 { + margin-left: 50%; +} + +.columns.is-mobile > .column.is-7 { + flex: none; + width: 58.33333%; +} + +.columns.is-mobile > .column.is-offset-7 { + margin-left: 58.33333%; +} + +.columns.is-mobile > .column.is-8 { + flex: none; + width: 66.66667%; +} + +.columns.is-mobile > .column.is-offset-8 { + margin-left: 66.66667%; +} + +.columns.is-mobile > .column.is-9 { + flex: none; + width: 75%; +} + +.columns.is-mobile > .column.is-offset-9 { + margin-left: 75%; +} + +.columns.is-mobile > .column.is-10 { + flex: none; + width: 83.33333%; +} + +.columns.is-mobile > .column.is-offset-10 { + margin-left: 83.33333%; +} + +.columns.is-mobile > .column.is-11 { + flex: none; + width: 91.66667%; +} + +.columns.is-mobile > .column.is-offset-11 { + margin-left: 91.66667%; +} + +.columns.is-mobile > .column.is-12 { + flex: none; + width: 100%; +} + +.columns.is-mobile > .column.is-offset-12 { + margin-left: 100%; +} + +@media screen and (max-width: 768px) { + .column.is-narrow-mobile { + flex: none; + } + .column.is-full-mobile { + flex: none; + width: 100%; + } + .column.is-three-quarters-mobile { + flex: none; + width: 75%; + } + .column.is-two-thirds-mobile { + flex: none; + width: 66.6666%; + } + .column.is-half-mobile { + flex: none; + width: 50%; + } + .column.is-one-third-mobile { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-mobile { + flex: none; + width: 25%; + } + .column.is-one-fifth-mobile { + flex: none; + width: 20%; + } + .column.is-two-fifths-mobile { + flex: none; + width: 40%; + } + .column.is-three-fifths-mobile { + flex: none; + width: 60%; + } + .column.is-four-fifths-mobile { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-mobile { + margin-left: 75%; + } + .column.is-offset-two-thirds-mobile { + margin-left: 66.6666%; + } + .column.is-offset-half-mobile { + margin-left: 50%; + } + .column.is-offset-one-third-mobile { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-mobile { + margin-left: 25%; + } + .column.is-offset-one-fifth-mobile { + margin-left: 20%; + } + .column.is-offset-two-fifths-mobile { + margin-left: 40%; + } + .column.is-offset-three-fifths-mobile { + margin-left: 60%; + } + .column.is-offset-four-fifths-mobile { + margin-left: 80%; + } + .column.is-0-mobile { + flex: none; + width: 0%; + } + .column.is-offset-0-mobile { + margin-left: 0%; + } + .column.is-1-mobile { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-mobile { + margin-left: 8.33333%; + } + .column.is-2-mobile { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-mobile { + margin-left: 16.66667%; + } + .column.is-3-mobile { + flex: none; + width: 25%; + } + .column.is-offset-3-mobile { + margin-left: 25%; + } + .column.is-4-mobile { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-mobile { + margin-left: 33.33333%; + } + .column.is-5-mobile { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-mobile { + margin-left: 41.66667%; + } + .column.is-6-mobile { + flex: none; + width: 50%; + } + .column.is-offset-6-mobile { + margin-left: 50%; + } + .column.is-7-mobile { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-mobile { + margin-left: 58.33333%; + } + .column.is-8-mobile { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-mobile { + margin-left: 66.66667%; + } + .column.is-9-mobile { + flex: none; + width: 75%; + } + .column.is-offset-9-mobile { + margin-left: 75%; + } + .column.is-10-mobile { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-mobile { + margin-left: 83.33333%; + } + .column.is-11-mobile { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-mobile { + margin-left: 91.66667%; + } + .column.is-12-mobile { + flex: none; + width: 100%; + } + .column.is-offset-12-mobile { + margin-left: 100%; + } +} + +@media screen and (min-width: 769px), print { + .column.is-narrow, .column.is-narrow-tablet { + flex: none; + } + .column.is-full, .column.is-full-tablet { + flex: none; + width: 100%; + } + .column.is-three-quarters, .column.is-three-quarters-tablet { + flex: none; + width: 75%; + } + .column.is-two-thirds, .column.is-two-thirds-tablet { + flex: none; + width: 66.6666%; + } + .column.is-half, .column.is-half-tablet { + flex: none; + width: 50%; + } + .column.is-one-third, .column.is-one-third-tablet { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter, .column.is-one-quarter-tablet { + flex: none; + width: 25%; + } + .column.is-one-fifth, .column.is-one-fifth-tablet { + flex: none; + width: 20%; + } + .column.is-two-fifths, .column.is-two-fifths-tablet { + flex: none; + width: 40%; + } + .column.is-three-fifths, .column.is-three-fifths-tablet { + flex: none; + width: 60%; + } + .column.is-four-fifths, .column.is-four-fifths-tablet { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters, .column.is-offset-three-quarters-tablet { + margin-left: 75%; + } + .column.is-offset-two-thirds, .column.is-offset-two-thirds-tablet { + margin-left: 66.6666%; + } + .column.is-offset-half, .column.is-offset-half-tablet { + margin-left: 50%; + } + .column.is-offset-one-third, .column.is-offset-one-third-tablet { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter, .column.is-offset-one-quarter-tablet { + margin-left: 25%; + } + .column.is-offset-one-fifth, .column.is-offset-one-fifth-tablet { + margin-left: 20%; + } + .column.is-offset-two-fifths, .column.is-offset-two-fifths-tablet { + margin-left: 40%; + } + .column.is-offset-three-fifths, .column.is-offset-three-fifths-tablet { + margin-left: 60%; + } + .column.is-offset-four-fifths, .column.is-offset-four-fifths-tablet { + margin-left: 80%; + } + .column.is-0, .column.is-0-tablet { + flex: none; + width: 0%; + } + .column.is-offset-0, .column.is-offset-0-tablet { + margin-left: 0%; + } + .column.is-1, .column.is-1-tablet { + flex: none; + width: 8.33333%; + } + .column.is-offset-1, .column.is-offset-1-tablet { + margin-left: 8.33333%; + } + .column.is-2, .column.is-2-tablet { + flex: none; + width: 16.66667%; + } + .column.is-offset-2, .column.is-offset-2-tablet { + margin-left: 16.66667%; + } + .column.is-3, .column.is-3-tablet { + flex: none; + width: 25%; + } + .column.is-offset-3, .column.is-offset-3-tablet { + margin-left: 25%; + } + .column.is-4, .column.is-4-tablet { + flex: none; + width: 33.33333%; + } + .column.is-offset-4, .column.is-offset-4-tablet { + margin-left: 33.33333%; + } + .column.is-5, .column.is-5-tablet { + flex: none; + width: 41.66667%; + } + .column.is-offset-5, .column.is-offset-5-tablet { + margin-left: 41.66667%; + } + .column.is-6, .column.is-6-tablet { + flex: none; + width: 50%; + } + .column.is-offset-6, .column.is-offset-6-tablet { + margin-left: 50%; + } + .column.is-7, .column.is-7-tablet { + flex: none; + width: 58.33333%; + } + .column.is-offset-7, .column.is-offset-7-tablet { + margin-left: 58.33333%; + } + .column.is-8, .column.is-8-tablet { + flex: none; + width: 66.66667%; + } + .column.is-offset-8, .column.is-offset-8-tablet { + margin-left: 66.66667%; + } + .column.is-9, .column.is-9-tablet { + flex: none; + width: 75%; + } + .column.is-offset-9, .column.is-offset-9-tablet { + margin-left: 75%; + } + .column.is-10, .column.is-10-tablet { + flex: none; + width: 83.33333%; + } + .column.is-offset-10, .column.is-offset-10-tablet { + margin-left: 83.33333%; + } + .column.is-11, .column.is-11-tablet { + flex: none; + width: 91.66667%; + } + .column.is-offset-11, .column.is-offset-11-tablet { + margin-left: 91.66667%; + } + .column.is-12, .column.is-12-tablet { + flex: none; + width: 100%; + } + .column.is-offset-12, .column.is-offset-12-tablet { + margin-left: 100%; + } +} + +@media screen and (max-width: 1023px) { + .column.is-narrow-touch { + flex: none; + } + .column.is-full-touch { + flex: none; + width: 100%; + } + .column.is-three-quarters-touch { + flex: none; + width: 75%; + } + .column.is-two-thirds-touch { + flex: none; + width: 66.6666%; + } + .column.is-half-touch { + flex: none; + width: 50%; + } + .column.is-one-third-touch { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-touch { + flex: none; + width: 25%; + } + .column.is-one-fifth-touch { + flex: none; + width: 20%; + } + .column.is-two-fifths-touch { + flex: none; + width: 40%; + } + .column.is-three-fifths-touch { + flex: none; + width: 60%; + } + .column.is-four-fifths-touch { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-touch { + margin-left: 75%; + } + .column.is-offset-two-thirds-touch { + margin-left: 66.6666%; + } + .column.is-offset-half-touch { + margin-left: 50%; + } + .column.is-offset-one-third-touch { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-touch { + margin-left: 25%; + } + .column.is-offset-one-fifth-touch { + margin-left: 20%; + } + .column.is-offset-two-fifths-touch { + margin-left: 40%; + } + .column.is-offset-three-fifths-touch { + margin-left: 60%; + } + .column.is-offset-four-fifths-touch { + margin-left: 80%; + } + .column.is-0-touch { + flex: none; + width: 0%; + } + .column.is-offset-0-touch { + margin-left: 0%; + } + .column.is-1-touch { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-touch { + margin-left: 8.33333%; + } + .column.is-2-touch { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-touch { + margin-left: 16.66667%; + } + .column.is-3-touch { + flex: none; + width: 25%; + } + .column.is-offset-3-touch { + margin-left: 25%; + } + .column.is-4-touch { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-touch { + margin-left: 33.33333%; + } + .column.is-5-touch { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-touch { + margin-left: 41.66667%; + } + .column.is-6-touch { + flex: none; + width: 50%; + } + .column.is-offset-6-touch { + margin-left: 50%; + } + .column.is-7-touch { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-touch { + margin-left: 58.33333%; + } + .column.is-8-touch { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-touch { + margin-left: 66.66667%; + } + .column.is-9-touch { + flex: none; + width: 75%; + } + .column.is-offset-9-touch { + margin-left: 75%; + } + .column.is-10-touch { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-touch { + margin-left: 83.33333%; + } + .column.is-11-touch { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-touch { + margin-left: 91.66667%; + } + .column.is-12-touch { + flex: none; + width: 100%; + } + .column.is-offset-12-touch { + margin-left: 100%; + } +} + +@media screen and (min-width: 1024px) { + .column.is-narrow-desktop { + flex: none; + } + .column.is-full-desktop { + flex: none; + width: 100%; + } + .column.is-three-quarters-desktop { + flex: none; + width: 75%; + } + .column.is-two-thirds-desktop { + flex: none; + width: 66.6666%; + } + .column.is-half-desktop { + flex: none; + width: 50%; + } + .column.is-one-third-desktop { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-desktop { + flex: none; + width: 25%; + } + .column.is-one-fifth-desktop { + flex: none; + width: 20%; + } + .column.is-two-fifths-desktop { + flex: none; + width: 40%; + } + .column.is-three-fifths-desktop { + flex: none; + width: 60%; + } + .column.is-four-fifths-desktop { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-desktop { + margin-left: 75%; + } + .column.is-offset-two-thirds-desktop { + margin-left: 66.6666%; + } + .column.is-offset-half-desktop { + margin-left: 50%; + } + .column.is-offset-one-third-desktop { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-desktop { + margin-left: 25%; + } + .column.is-offset-one-fifth-desktop { + margin-left: 20%; + } + .column.is-offset-two-fifths-desktop { + margin-left: 40%; + } + .column.is-offset-three-fifths-desktop { + margin-left: 60%; + } + .column.is-offset-four-fifths-desktop { + margin-left: 80%; + } + .column.is-0-desktop { + flex: none; + width: 0%; + } + .column.is-offset-0-desktop { + margin-left: 0%; + } + .column.is-1-desktop { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-desktop { + margin-left: 8.33333%; + } + .column.is-2-desktop { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-desktop { + margin-left: 16.66667%; + } + .column.is-3-desktop { + flex: none; + width: 25%; + } + .column.is-offset-3-desktop { + margin-left: 25%; + } + .column.is-4-desktop { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-desktop { + margin-left: 33.33333%; + } + .column.is-5-desktop { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-desktop { + margin-left: 41.66667%; + } + .column.is-6-desktop { + flex: none; + width: 50%; + } + .column.is-offset-6-desktop { + margin-left: 50%; + } + .column.is-7-desktop { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-desktop { + margin-left: 58.33333%; + } + .column.is-8-desktop { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-desktop { + margin-left: 66.66667%; + } + .column.is-9-desktop { + flex: none; + width: 75%; + } + .column.is-offset-9-desktop { + margin-left: 75%; + } + .column.is-10-desktop { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-desktop { + margin-left: 83.33333%; + } + .column.is-11-desktop { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-desktop { + margin-left: 91.66667%; + } + .column.is-12-desktop { + flex: none; + width: 100%; + } + .column.is-offset-12-desktop { + margin-left: 100%; + } +} + +@media screen and (min-width: 1216px) { + .column.is-narrow-widescreen { + flex: none; + } + .column.is-full-widescreen { + flex: none; + width: 100%; + } + .column.is-three-quarters-widescreen { + flex: none; + width: 75%; + } + .column.is-two-thirds-widescreen { + flex: none; + width: 66.6666%; + } + .column.is-half-widescreen { + flex: none; + width: 50%; + } + .column.is-one-third-widescreen { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-widescreen { + flex: none; + width: 25%; + } + .column.is-one-fifth-widescreen { + flex: none; + width: 20%; + } + .column.is-two-fifths-widescreen { + flex: none; + width: 40%; + } + .column.is-three-fifths-widescreen { + flex: none; + width: 60%; + } + .column.is-four-fifths-widescreen { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-widescreen { + margin-left: 75%; + } + .column.is-offset-two-thirds-widescreen { + margin-left: 66.6666%; + } + .column.is-offset-half-widescreen { + margin-left: 50%; + } + .column.is-offset-one-third-widescreen { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-widescreen { + margin-left: 25%; + } + .column.is-offset-one-fifth-widescreen { + margin-left: 20%; + } + .column.is-offset-two-fifths-widescreen { + margin-left: 40%; + } + .column.is-offset-three-fifths-widescreen { + margin-left: 60%; + } + .column.is-offset-four-fifths-widescreen { + margin-left: 80%; + } + .column.is-0-widescreen { + flex: none; + width: 0%; + } + .column.is-offset-0-widescreen { + margin-left: 0%; + } + .column.is-1-widescreen { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-widescreen { + margin-left: 8.33333%; + } + .column.is-2-widescreen { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-widescreen { + margin-left: 16.66667%; + } + .column.is-3-widescreen { + flex: none; + width: 25%; + } + .column.is-offset-3-widescreen { + margin-left: 25%; + } + .column.is-4-widescreen { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-widescreen { + margin-left: 33.33333%; + } + .column.is-5-widescreen { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-widescreen { + margin-left: 41.66667%; + } + .column.is-6-widescreen { + flex: none; + width: 50%; + } + .column.is-offset-6-widescreen { + margin-left: 50%; + } + .column.is-7-widescreen { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-widescreen { + margin-left: 58.33333%; + } + .column.is-8-widescreen { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-widescreen { + margin-left: 66.66667%; + } + .column.is-9-widescreen { + flex: none; + width: 75%; + } + .column.is-offset-9-widescreen { + margin-left: 75%; + } + .column.is-10-widescreen { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-widescreen { + margin-left: 83.33333%; + } + .column.is-11-widescreen { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-widescreen { + margin-left: 91.66667%; + } + .column.is-12-widescreen { + flex: none; + width: 100%; + } + .column.is-offset-12-widescreen { + margin-left: 100%; + } +} + +@media screen and (min-width: 1408px) { + .column.is-narrow-fullhd { + flex: none; + } + .column.is-full-fullhd { + flex: none; + width: 100%; + } + .column.is-three-quarters-fullhd { + flex: none; + width: 75%; + } + .column.is-two-thirds-fullhd { + flex: none; + width: 66.6666%; + } + .column.is-half-fullhd { + flex: none; + width: 50%; + } + .column.is-one-third-fullhd { + flex: none; + width: 33.3333%; + } + .column.is-one-quarter-fullhd { + flex: none; + width: 25%; + } + .column.is-one-fifth-fullhd { + flex: none; + width: 20%; + } + .column.is-two-fifths-fullhd { + flex: none; + width: 40%; + } + .column.is-three-fifths-fullhd { + flex: none; + width: 60%; + } + .column.is-four-fifths-fullhd { + flex: none; + width: 80%; + } + .column.is-offset-three-quarters-fullhd { + margin-left: 75%; + } + .column.is-offset-two-thirds-fullhd { + margin-left: 66.6666%; + } + .column.is-offset-half-fullhd { + margin-left: 50%; + } + .column.is-offset-one-third-fullhd { + margin-left: 33.3333%; + } + .column.is-offset-one-quarter-fullhd { + margin-left: 25%; + } + .column.is-offset-one-fifth-fullhd { + margin-left: 20%; + } + .column.is-offset-two-fifths-fullhd { + margin-left: 40%; + } + .column.is-offset-three-fifths-fullhd { + margin-left: 60%; + } + .column.is-offset-four-fifths-fullhd { + margin-left: 80%; + } + .column.is-0-fullhd { + flex: none; + width: 0%; + } + .column.is-offset-0-fullhd { + margin-left: 0%; + } + .column.is-1-fullhd { + flex: none; + width: 8.33333%; + } + .column.is-offset-1-fullhd { + margin-left: 8.33333%; + } + .column.is-2-fullhd { + flex: none; + width: 16.66667%; + } + .column.is-offset-2-fullhd { + margin-left: 16.66667%; + } + .column.is-3-fullhd { + flex: none; + width: 25%; + } + .column.is-offset-3-fullhd { + margin-left: 25%; + } + .column.is-4-fullhd { + flex: none; + width: 33.33333%; + } + .column.is-offset-4-fullhd { + margin-left: 33.33333%; + } + .column.is-5-fullhd { + flex: none; + width: 41.66667%; + } + .column.is-offset-5-fullhd { + margin-left: 41.66667%; + } + .column.is-6-fullhd { + flex: none; + width: 50%; + } + .column.is-offset-6-fullhd { + margin-left: 50%; + } + .column.is-7-fullhd { + flex: none; + width: 58.33333%; + } + .column.is-offset-7-fullhd { + margin-left: 58.33333%; + } + .column.is-8-fullhd { + flex: none; + width: 66.66667%; + } + .column.is-offset-8-fullhd { + margin-left: 66.66667%; + } + .column.is-9-fullhd { + flex: none; + width: 75%; + } + .column.is-offset-9-fullhd { + margin-left: 75%; + } + .column.is-10-fullhd { + flex: none; + width: 83.33333%; + } + .column.is-offset-10-fullhd { + margin-left: 83.33333%; + } + .column.is-11-fullhd { + flex: none; + width: 91.66667%; + } + .column.is-offset-11-fullhd { + margin-left: 91.66667%; + } + .column.is-12-fullhd { + flex: none; + width: 100%; + } + .column.is-offset-12-fullhd { + margin-left: 100%; + } +} + +.columns { + margin-left: -0.75rem; + margin-right: -0.75rem; + margin-top: -0.75rem; +} + +.columns:last-child { + margin-bottom: -0.75rem; +} + +.columns:not(:last-child) { + margin-bottom: calc(1.5rem - 0.75rem); +} + +.columns.is-centered { + justify-content: center; +} + +.columns.is-gapless { + margin-left: 0; + margin-right: 0; + margin-top: 0; +} + +.columns.is-gapless > .column { + margin: 0; + padding: 0 !important; +} + +.columns.is-gapless:not(:last-child) { + margin-bottom: 1.5rem; +} + +.columns.is-gapless:last-child { + margin-bottom: 0; +} + +.columns.is-mobile { + display: flex; +} + +.columns.is-multiline { + flex-wrap: wrap; +} + +.columns.is-vcentered { + align-items: center; +} + +@media screen and (min-width: 769px), print { + .columns:not(.is-desktop) { + display: flex; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-desktop { + display: flex; + } +} + +.columns.is-variable { + --columnGap: 0.75rem; + margin-left: calc(-1 * var(--columnGap)); + margin-right: calc(-1 * var(--columnGap)); +} + +.columns.is-variable .column { + padding-left: var(--columnGap); + padding-right: var(--columnGap); +} + +.columns.is-variable.is-0 { + --columnGap: 0rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-0-mobile { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-0-tablet { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-0-tablet-only { + --columnGap: 0rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-0-touch { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-0-desktop { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-0-desktop-only { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-0-widescreen { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-0-widescreen-only { + --columnGap: 0rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-0-fullhd { + --columnGap: 0rem; + } +} + +.columns.is-variable.is-1 { + --columnGap: 0.25rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-1-mobile { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-1-tablet { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-1-tablet-only { + --columnGap: 0.25rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-1-touch { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-1-desktop { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-1-desktop-only { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-1-widescreen { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-1-widescreen-only { + --columnGap: 0.25rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-1-fullhd { + --columnGap: 0.25rem; + } +} + +.columns.is-variable.is-2 { + --columnGap: 0.5rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-2-mobile { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-2-tablet { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-2-tablet-only { + --columnGap: 0.5rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-2-touch { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-2-desktop { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-2-desktop-only { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-2-widescreen { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-2-widescreen-only { + --columnGap: 0.5rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-2-fullhd { + --columnGap: 0.5rem; + } +} + +.columns.is-variable.is-3 { + --columnGap: 0.75rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-3-mobile { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-3-tablet { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-3-tablet-only { + --columnGap: 0.75rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-3-touch { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-3-desktop { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-3-desktop-only { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-3-widescreen { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-3-widescreen-only { + --columnGap: 0.75rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-3-fullhd { + --columnGap: 0.75rem; + } +} + +.columns.is-variable.is-4 { + --columnGap: 1rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-4-mobile { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-4-tablet { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-4-tablet-only { + --columnGap: 1rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-4-touch { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-4-desktop { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-4-desktop-only { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-4-widescreen { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-4-widescreen-only { + --columnGap: 1rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-4-fullhd { + --columnGap: 1rem; + } +} + +.columns.is-variable.is-5 { + --columnGap: 1.25rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-5-mobile { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-5-tablet { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-5-tablet-only { + --columnGap: 1.25rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-5-touch { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-5-desktop { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-5-desktop-only { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-5-widescreen { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-5-widescreen-only { + --columnGap: 1.25rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-5-fullhd { + --columnGap: 1.25rem; + } +} + +.columns.is-variable.is-6 { + --columnGap: 1.5rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-6-mobile { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-6-tablet { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-6-tablet-only { + --columnGap: 1.5rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-6-touch { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-6-desktop { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-6-desktop-only { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-6-widescreen { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-6-widescreen-only { + --columnGap: 1.5rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-6-fullhd { + --columnGap: 1.5rem; + } +} + +.columns.is-variable.is-7 { + --columnGap: 1.75rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-7-mobile { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-7-tablet { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-7-tablet-only { + --columnGap: 1.75rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-7-touch { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-7-desktop { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-7-desktop-only { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-7-widescreen { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-7-widescreen-only { + --columnGap: 1.75rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-7-fullhd { + --columnGap: 1.75rem; + } +} + +.columns.is-variable.is-8 { + --columnGap: 2rem; +} + +@media screen and (max-width: 768px) { + .columns.is-variable.is-8-mobile { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 769px), print { + .columns.is-variable.is-8-tablet { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .columns.is-variable.is-8-tablet-only { + --columnGap: 2rem; + } +} + +@media screen and (max-width: 1023px) { + .columns.is-variable.is-8-touch { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1024px) { + .columns.is-variable.is-8-desktop { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .columns.is-variable.is-8-desktop-only { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1216px) { + .columns.is-variable.is-8-widescreen { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .columns.is-variable.is-8-widescreen-only { + --columnGap: 2rem; + } +} + +@media screen and (min-width: 1408px) { + .columns.is-variable.is-8-fullhd { + --columnGap: 2rem; + } +} + +.tile { + align-items: stretch; + display: block; + flex-basis: 0; + flex-grow: 1; + flex-shrink: 1; + min-height: -webkit-min-content; + min-height: -moz-min-content; + min-height: min-content; +} + +.tile.is-ancestor { + margin-left: -0.75rem; + margin-right: -0.75rem; + margin-top: -0.75rem; +} + +.tile.is-ancestor:last-child { + margin-bottom: -0.75rem; +} + +.tile.is-ancestor:not(:last-child) { + margin-bottom: 0.75rem; +} + +.tile.is-child { + margin: 0 !important; +} + +.tile.is-parent { + padding: 0.75rem; +} + +.tile.is-vertical { + flex-direction: column; +} + +.tile.is-vertical > .tile.is-child:not(:last-child) { + margin-bottom: 1.5rem !important; +} + +@media screen and (min-width: 769px), print { + .tile:not(.is-child) { + display: flex; + } + .tile.is-1 { + flex: none; + width: 8.33333%; + } + .tile.is-2 { + flex: none; + width: 16.66667%; + } + .tile.is-3 { + flex: none; + width: 25%; + } + .tile.is-4 { + flex: none; + width: 33.33333%; + } + .tile.is-5 { + flex: none; + width: 41.66667%; + } + .tile.is-6 { + flex: none; + width: 50%; + } + .tile.is-7 { + flex: none; + width: 58.33333%; + } + .tile.is-8 { + flex: none; + width: 66.66667%; + } + .tile.is-9 { + flex: none; + width: 75%; + } + .tile.is-10 { + flex: none; + width: 83.33333%; + } + .tile.is-11 { + flex: none; + width: 91.66667%; + } + .tile.is-12 { + flex: none; + width: 100%; + } +} + +.has-text-white { + color: white !important; +} + +a.has-text-white:hover, a.has-text-white:focus { + color: #e6e6e6 !important; +} + +.has-background-white { + background-color: white !important; +} + +.has-text-black { + color: #0a0a0a !important; +} + +a.has-text-black:hover, a.has-text-black:focus { + color: black !important; +} + +.has-background-black { + background-color: #0a0a0a !important; +} + +.has-text-light { + color: whitesmoke !important; +} + +a.has-text-light:hover, a.has-text-light:focus { + color: #dbdbdb !important; +} + +.has-background-light { + background-color: whitesmoke !important; +} + +.has-text-dark { + color: #363636 !important; +} + +a.has-text-dark:hover, a.has-text-dark:focus { + color: #1c1c1c !important; +} + +.has-background-dark { + background-color: #363636 !important; +} + +.has-text-primary { + color: #00d1b2 !important; +} + +a.has-text-primary:hover, a.has-text-primary:focus { + color: #009e86 !important; +} + +.has-background-primary { + background-color: #00d1b2 !important; +} + +.has-text-primary-light { + color: #ebfffc !important; +} + +a.has-text-primary-light:hover, a.has-text-primary-light:focus { + color: #b8fff4 !important; +} + +.has-background-primary-light { + background-color: #ebfffc !important; +} + +.has-text-primary-dark { + color: #00947e !important; +} + +a.has-text-primary-dark:hover, a.has-text-primary-dark:focus { + color: #00c7a9 !important; +} + +.has-background-primary-dark { + background-color: #00947e !important; +} + +.has-text-link { + color: #3273dc !important; +} + +a.has-text-link:hover, a.has-text-link:focus { + color: #205bbc !important; +} + +.has-background-link { + background-color: #3273dc !important; +} + +.has-text-link-light { + color: #eef3fc !important; +} + +a.has-text-link-light:hover, a.has-text-link-light:focus { + color: #c2d5f5 !important; +} + +.has-background-link-light { + background-color: #eef3fc !important; +} + +.has-text-link-dark { + color: #2160c4 !important; +} + +a.has-text-link-dark:hover, a.has-text-link-dark:focus { + color: #3b79de !important; +} + +.has-background-link-dark { + background-color: #2160c4 !important; +} + +.has-text-info { + color: #3298dc !important; +} + +a.has-text-info:hover, a.has-text-info:focus { + color: #207dbc !important; +} + +.has-background-info { + background-color: #3298dc !important; +} + +.has-text-info-light { + color: #eef6fc !important; +} + +a.has-text-info-light:hover, a.has-text-info-light:focus { + color: #c2e0f5 !important; +} + +.has-background-info-light { + background-color: #eef6fc !important; +} + +.has-text-info-dark { + color: #1d72aa !important; +} + +a.has-text-info-dark:hover, a.has-text-info-dark:focus { + color: #248fd6 !important; +} + +.has-background-info-dark { + background-color: #1d72aa !important; +} + +.has-text-success { + color: #48c774 !important; +} + +a.has-text-success:hover, a.has-text-success:focus { + color: #34a85c !important; +} + +.has-background-success { + background-color: #48c774 !important; +} + +.has-text-success-light { + color: #effaf3 !important; +} + +a.has-text-success-light:hover, a.has-text-success-light:focus { + color: #c8eed6 !important; +} + +.has-background-success-light { + background-color: #effaf3 !important; +} + +.has-text-success-dark { + color: #257942 !important; +} + +a.has-text-success-dark:hover, a.has-text-success-dark:focus { + color: #31a058 !important; +} + +.has-background-success-dark { + background-color: #257942 !important; +} + +.has-text-warning { + color: #ffdd57 !important; +} + +a.has-text-warning:hover, a.has-text-warning:focus { + color: #ffd324 !important; +} + +.has-background-warning { + background-color: #ffdd57 !important; +} + +.has-text-warning-light { + color: #fffbeb !important; +} + +a.has-text-warning-light:hover, a.has-text-warning-light:focus { + color: #fff1b8 !important; +} + +.has-background-warning-light { + background-color: #fffbeb !important; +} + +.has-text-warning-dark { + color: #947600 !important; +} + +a.has-text-warning-dark:hover, a.has-text-warning-dark:focus { + color: #c79f00 !important; +} + +.has-background-warning-dark { + background-color: #947600 !important; +} + +.has-text-danger { + color: #f14668 !important; +} + +a.has-text-danger:hover, a.has-text-danger:focus { + color: #ee1742 !important; +} + +.has-background-danger { + background-color: #f14668 !important; +} + +.has-text-danger-light { + color: #feecf0 !important; +} + +a.has-text-danger-light:hover, a.has-text-danger-light:focus { + color: #fabdc9 !important; +} + +.has-background-danger-light { + background-color: #feecf0 !important; +} + +.has-text-danger-dark { + color: #cc0f35 !important; +} + +a.has-text-danger-dark:hover, a.has-text-danger-dark:focus { + color: #ee2049 !important; +} + +.has-background-danger-dark { + background-color: #cc0f35 !important; +} + +.has-text-black-bis { + color: #121212 !important; +} + +.has-background-black-bis { + background-color: #121212 !important; +} + +.has-text-black-ter { + color: #242424 !important; +} + +.has-background-black-ter { + background-color: #242424 !important; +} + +.has-text-grey-darker { + color: #363636 !important; +} + +.has-background-grey-darker { + background-color: #363636 !important; +} + +.has-text-grey-dark { + color: #4a4a4a !important; +} + +.has-background-grey-dark { + background-color: #4a4a4a !important; +} + +.has-text-grey { + color: #7a7a7a !important; +} + +.has-background-grey { + background-color: #7a7a7a !important; +} + +.has-text-grey-light { + color: #b5b5b5 !important; +} + +.has-background-grey-light { + background-color: #b5b5b5 !important; +} + +.has-text-grey-lighter { + color: #dbdbdb !important; +} + +.has-background-grey-lighter { + background-color: #dbdbdb !important; +} + +.has-text-white-ter { + color: whitesmoke !important; +} + +.has-background-white-ter { + background-color: whitesmoke !important; +} + +.has-text-white-bis { + color: #fafafa !important; +} + +.has-background-white-bis { + background-color: #fafafa !important; +} + +.is-clearfix::after { + clear: both; + content: " "; + display: table; +} + +.is-pulled-left { + float: left !important; +} + +.is-pulled-right { + float: right !important; +} + +.is-radiusless { + border-radius: 0 !important; +} + +.is-shadowless { + box-shadow: none !important; +} + +.is-clipped { + overflow: hidden !important; +} + +.is-relative { + position: relative !important; +} + +.is-marginless { + margin: 0 !important; +} + +.is-paddingless { + padding: 0 !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mr-0 { + margin-right: 0 !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.ml-0 { + margin-left: 0 !important; +} + +.mx-0 { + margin-left: 0 !important; + margin-right: 0 !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mr-1 { + margin-right: 0.25rem !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.ml-1 { + margin-left: 0.25rem !important; +} + +.mx-1 { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mr-2 { + margin-right: 0.5rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.ml-2 { + margin-left: 0.5rem !important; +} + +.mx-2 { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.mt-3 { + margin-top: 0.75rem !important; +} + +.mr-3 { + margin-right: 0.75rem !important; +} + +.mb-3 { + margin-bottom: 0.75rem !important; +} + +.ml-3 { + margin-left: 0.75rem !important; +} + +.mx-3 { + margin-left: 0.75rem !important; + margin-right: 0.75rem !important; +} + +.my-3 { + margin-top: 0.75rem !important; + margin-bottom: 0.75rem !important; +} + +.mt-4 { + margin-top: 1rem !important; +} + +.mr-4 { + margin-right: 1rem !important; +} + +.mb-4 { + margin-bottom: 1rem !important; +} + +.ml-4 { + margin-left: 1rem !important; +} + +.mx-4 { + margin-left: 1rem !important; + margin-right: 1rem !important; +} + +.my-4 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.mt-5 { + margin-top: 1.5rem !important; +} + +.mr-5 { + margin-right: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 1.5rem !important; +} + +.ml-5 { + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-left: 1.5rem !important; + margin-right: 1.5rem !important; +} + +.my-5 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.mt-6 { + margin-top: 3rem !important; +} + +.mr-6 { + margin-right: 3rem !important; +} + +.mb-6 { + margin-bottom: 3rem !important; +} + +.ml-6 { + margin-left: 3rem !important; +} + +.mx-6 { + margin-left: 3rem !important; + margin-right: 3rem !important; +} + +.my-6 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pr-0 { + padding-right: 0 !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pl-0 { + padding-left: 0 !important; +} + +.px-0 { + padding-left: 0 !important; + padding-right: 0 !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pr-1 { + padding-right: 0.25rem !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pl-1 { + padding-left: 0.25rem !important; +} + +.px-1 { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pr-2 { + padding-right: 0.5rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pl-2 { + padding-left: 0.5rem !important; +} + +.px-2 { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.pt-3 { + padding-top: 0.75rem !important; +} + +.pr-3 { + padding-right: 0.75rem !important; +} + +.pb-3 { + padding-bottom: 0.75rem !important; +} + +.pl-3 { + padding-left: 0.75rem !important; +} + +.px-3 { + padding-left: 0.75rem !important; + padding-right: 0.75rem !important; +} + +.py-3 { + padding-top: 0.75rem !important; + padding-bottom: 0.75rem !important; +} + +.pt-4 { + padding-top: 1rem !important; +} + +.pr-4 { + padding-right: 1rem !important; +} + +.pb-4 { + padding-bottom: 1rem !important; +} + +.pl-4 { + padding-left: 1rem !important; +} + +.px-4 { + padding-left: 1rem !important; + padding-right: 1rem !important; +} + +.py-4 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.pt-5 { + padding-top: 1.5rem !important; +} + +.pr-5 { + padding-right: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 1.5rem !important; +} + +.pl-5 { + padding-left: 1.5rem !important; +} + +.px-5 { + padding-left: 1.5rem !important; + padding-right: 1.5rem !important; +} + +.py-5 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.pt-6 { + padding-top: 3rem !important; +} + +.pr-6 { + padding-right: 3rem !important; +} + +.pb-6 { + padding-bottom: 3rem !important; +} + +.pl-6 { + padding-left: 3rem !important; +} + +.px-6 { + padding-left: 3rem !important; + padding-right: 3rem !important; +} + +.py-6 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.is-size-1 { + font-size: 3rem !important; +} + +.is-size-2 { + font-size: 2.5rem !important; +} + +.is-size-3 { + font-size: 2rem !important; +} + +.is-size-4 { + font-size: 1.5rem !important; +} + +.is-size-5 { + font-size: 1.25rem !important; +} + +.is-size-6 { + font-size: 1rem !important; +} + +.is-size-7 { + font-size: 0.75rem !important; +} + +@media screen and (max-width: 768px) { + .is-size-1-mobile { + font-size: 3rem !important; + } + .is-size-2-mobile { + font-size: 2.5rem !important; + } + .is-size-3-mobile { + font-size: 2rem !important; + } + .is-size-4-mobile { + font-size: 1.5rem !important; + } + .is-size-5-mobile { + font-size: 1.25rem !important; + } + .is-size-6-mobile { + font-size: 1rem !important; + } + .is-size-7-mobile { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 769px), print { + .is-size-1-tablet { + font-size: 3rem !important; + } + .is-size-2-tablet { + font-size: 2.5rem !important; + } + .is-size-3-tablet { + font-size: 2rem !important; + } + .is-size-4-tablet { + font-size: 1.5rem !important; + } + .is-size-5-tablet { + font-size: 1.25rem !important; + } + .is-size-6-tablet { + font-size: 1rem !important; + } + .is-size-7-tablet { + font-size: 0.75rem !important; + } +} + +@media screen and (max-width: 1023px) { + .is-size-1-touch { + font-size: 3rem !important; + } + .is-size-2-touch { + font-size: 2.5rem !important; + } + .is-size-3-touch { + font-size: 2rem !important; + } + .is-size-4-touch { + font-size: 1.5rem !important; + } + .is-size-5-touch { + font-size: 1.25rem !important; + } + .is-size-6-touch { + font-size: 1rem !important; + } + .is-size-7-touch { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 1024px) { + .is-size-1-desktop { + font-size: 3rem !important; + } + .is-size-2-desktop { + font-size: 2.5rem !important; + } + .is-size-3-desktop { + font-size: 2rem !important; + } + .is-size-4-desktop { + font-size: 1.5rem !important; + } + .is-size-5-desktop { + font-size: 1.25rem !important; + } + .is-size-6-desktop { + font-size: 1rem !important; + } + .is-size-7-desktop { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 1216px) { + .is-size-1-widescreen { + font-size: 3rem !important; + } + .is-size-2-widescreen { + font-size: 2.5rem !important; + } + .is-size-3-widescreen { + font-size: 2rem !important; + } + .is-size-4-widescreen { + font-size: 1.5rem !important; + } + .is-size-5-widescreen { + font-size: 1.25rem !important; + } + .is-size-6-widescreen { + font-size: 1rem !important; + } + .is-size-7-widescreen { + font-size: 0.75rem !important; + } +} + +@media screen and (min-width: 1408px) { + .is-size-1-fullhd { + font-size: 3rem !important; + } + .is-size-2-fullhd { + font-size: 2.5rem !important; + } + .is-size-3-fullhd { + font-size: 2rem !important; + } + .is-size-4-fullhd { + font-size: 1.5rem !important; + } + .is-size-5-fullhd { + font-size: 1.25rem !important; + } + .is-size-6-fullhd { + font-size: 1rem !important; + } + .is-size-7-fullhd { + font-size: 0.75rem !important; + } +} + +.has-text-centered { + text-align: center !important; +} + +.has-text-justified { + text-align: justify !important; +} + +.has-text-left { + text-align: left !important; +} + +.has-text-right { + text-align: right !important; +} + +@media screen and (max-width: 768px) { + .has-text-centered-mobile { + text-align: center !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-centered-tablet { + text-align: center !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-centered-tablet-only { + text-align: center !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-centered-touch { + text-align: center !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-centered-desktop { + text-align: center !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-centered-desktop-only { + text-align: center !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-centered-widescreen { + text-align: center !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-centered-widescreen-only { + text-align: center !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-centered-fullhd { + text-align: center !important; + } +} + +@media screen and (max-width: 768px) { + .has-text-justified-mobile { + text-align: justify !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-justified-tablet { + text-align: justify !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-justified-tablet-only { + text-align: justify !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-justified-touch { + text-align: justify !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-justified-desktop { + text-align: justify !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-justified-desktop-only { + text-align: justify !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-justified-widescreen { + text-align: justify !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-justified-widescreen-only { + text-align: justify !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-justified-fullhd { + text-align: justify !important; + } +} + +@media screen and (max-width: 768px) { + .has-text-left-mobile { + text-align: left !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-left-tablet { + text-align: left !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-left-tablet-only { + text-align: left !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-left-touch { + text-align: left !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-left-desktop { + text-align: left !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-left-desktop-only { + text-align: left !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-left-widescreen { + text-align: left !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-left-widescreen-only { + text-align: left !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-left-fullhd { + text-align: left !important; + } +} + +@media screen and (max-width: 768px) { + .has-text-right-mobile { + text-align: right !important; + } +} + +@media screen and (min-width: 769px), print { + .has-text-right-tablet { + text-align: right !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .has-text-right-tablet-only { + text-align: right !important; + } +} + +@media screen and (max-width: 1023px) { + .has-text-right-touch { + text-align: right !important; + } +} + +@media screen and (min-width: 1024px) { + .has-text-right-desktop { + text-align: right !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .has-text-right-desktop-only { + text-align: right !important; + } +} + +@media screen and (min-width: 1216px) { + .has-text-right-widescreen { + text-align: right !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .has-text-right-widescreen-only { + text-align: right !important; + } +} + +@media screen and (min-width: 1408px) { + .has-text-right-fullhd { + text-align: right !important; + } +} + +.is-capitalized { + text-transform: capitalize !important; +} + +.is-lowercase { + text-transform: lowercase !important; +} + +.is-uppercase { + text-transform: uppercase !important; +} + +.is-italic { + font-style: italic !important; +} + +.has-text-weight-light { + font-weight: 300 !important; +} + +.has-text-weight-normal { + font-weight: 400 !important; +} + +.has-text-weight-medium { + font-weight: 500 !important; +} + +.has-text-weight-semibold { + font-weight: 600 !important; +} + +.has-text-weight-bold { + font-weight: 700 !important; +} + +.is-family-primary { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; +} + +.is-family-secondary { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; +} + +.is-family-sans-serif { + font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif !important; +} + +.is-family-monospace { + font-family: monospace !important; +} + +.is-family-code { + font-family: monospace !important; +} + +.is-block { + display: block !important; +} + +@media screen and (max-width: 768px) { + .is-block-mobile { + display: block !important; + } +} + +@media screen and (min-width: 769px), print { + .is-block-tablet { + display: block !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-block-tablet-only { + display: block !important; + } +} + +@media screen and (max-width: 1023px) { + .is-block-touch { + display: block !important; + } +} + +@media screen and (min-width: 1024px) { + .is-block-desktop { + display: block !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-block-desktop-only { + display: block !important; + } +} + +@media screen and (min-width: 1216px) { + .is-block-widescreen { + display: block !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-block-widescreen-only { + display: block !important; + } +} + +@media screen and (min-width: 1408px) { + .is-block-fullhd { + display: block !important; + } +} + +.is-flex { + display: flex !important; +} + +@media screen and (max-width: 768px) { + .is-flex-mobile { + display: flex !important; + } +} + +@media screen and (min-width: 769px), print { + .is-flex-tablet { + display: flex !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-flex-tablet-only { + display: flex !important; + } +} + +@media screen and (max-width: 1023px) { + .is-flex-touch { + display: flex !important; + } +} + +@media screen and (min-width: 1024px) { + .is-flex-desktop { + display: flex !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-flex-desktop-only { + display: flex !important; + } +} + +@media screen and (min-width: 1216px) { + .is-flex-widescreen { + display: flex !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-flex-widescreen-only { + display: flex !important; + } +} + +@media screen and (min-width: 1408px) { + .is-flex-fullhd { + display: flex !important; + } +} + +.is-inline { + display: inline !important; +} + +@media screen and (max-width: 768px) { + .is-inline-mobile { + display: inline !important; + } +} + +@media screen and (min-width: 769px), print { + .is-inline-tablet { + display: inline !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-inline-tablet-only { + display: inline !important; + } +} + +@media screen and (max-width: 1023px) { + .is-inline-touch { + display: inline !important; + } +} + +@media screen and (min-width: 1024px) { + .is-inline-desktop { + display: inline !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-inline-desktop-only { + display: inline !important; + } +} + +@media screen and (min-width: 1216px) { + .is-inline-widescreen { + display: inline !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-inline-widescreen-only { + display: inline !important; + } +} + +@media screen and (min-width: 1408px) { + .is-inline-fullhd { + display: inline !important; + } +} + +.is-inline-block { + display: inline-block !important; +} + +@media screen and (max-width: 768px) { + .is-inline-block-mobile { + display: inline-block !important; + } +} + +@media screen and (min-width: 769px), print { + .is-inline-block-tablet { + display: inline-block !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-inline-block-tablet-only { + display: inline-block !important; + } +} + +@media screen and (max-width: 1023px) { + .is-inline-block-touch { + display: inline-block !important; + } +} + +@media screen and (min-width: 1024px) { + .is-inline-block-desktop { + display: inline-block !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-inline-block-desktop-only { + display: inline-block !important; + } +} + +@media screen and (min-width: 1216px) { + .is-inline-block-widescreen { + display: inline-block !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-inline-block-widescreen-only { + display: inline-block !important; + } +} + +@media screen and (min-width: 1408px) { + .is-inline-block-fullhd { + display: inline-block !important; + } +} + +.is-inline-flex { + display: inline-flex !important; +} + +@media screen and (max-width: 768px) { + .is-inline-flex-mobile { + display: inline-flex !important; + } +} + +@media screen and (min-width: 769px), print { + .is-inline-flex-tablet { + display: inline-flex !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-inline-flex-tablet-only { + display: inline-flex !important; + } +} + +@media screen and (max-width: 1023px) { + .is-inline-flex-touch { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1024px) { + .is-inline-flex-desktop { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-inline-flex-desktop-only { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1216px) { + .is-inline-flex-widescreen { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-inline-flex-widescreen-only { + display: inline-flex !important; + } +} + +@media screen and (min-width: 1408px) { + .is-inline-flex-fullhd { + display: inline-flex !important; + } +} + +.is-hidden { + display: none !important; +} + +.is-sr-only { + border: none !important; + clip: rect(0, 0, 0, 0) !important; + height: 0.01em !important; + overflow: hidden !important; + padding: 0 !important; + position: absolute !important; + white-space: nowrap !important; + width: 0.01em !important; +} + +@media screen and (max-width: 768px) { + .is-hidden-mobile { + display: none !important; + } +} + +@media screen and (min-width: 769px), print { + .is-hidden-tablet { + display: none !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-hidden-tablet-only { + display: none !important; + } +} + +@media screen and (max-width: 1023px) { + .is-hidden-touch { + display: none !important; + } +} + +@media screen and (min-width: 1024px) { + .is-hidden-desktop { + display: none !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-hidden-desktop-only { + display: none !important; + } +} + +@media screen and (min-width: 1216px) { + .is-hidden-widescreen { + display: none !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-hidden-widescreen-only { + display: none !important; + } +} + +@media screen and (min-width: 1408px) { + .is-hidden-fullhd { + display: none !important; + } +} + +.is-invisible { + visibility: hidden !important; +} + +@media screen and (max-width: 768px) { + .is-invisible-mobile { + visibility: hidden !important; + } +} + +@media screen and (min-width: 769px), print { + .is-invisible-tablet { + visibility: hidden !important; + } +} + +@media screen and (min-width: 769px) and (max-width: 1023px) { + .is-invisible-tablet-only { + visibility: hidden !important; + } +} + +@media screen and (max-width: 1023px) { + .is-invisible-touch { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1024px) { + .is-invisible-desktop { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1024px) and (max-width: 1215px) { + .is-invisible-desktop-only { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1216px) { + .is-invisible-widescreen { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1216px) and (max-width: 1407px) { + .is-invisible-widescreen-only { + visibility: hidden !important; + } +} + +@media screen and (min-width: 1408px) { + .is-invisible-fullhd { + visibility: hidden !important; + } +} + +.hero { + align-items: stretch; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.hero .navbar { + background: none; +} + +.hero .tabs ul { + border-bottom: none; +} + +.hero.is-white { + background-color: white; + color: #0a0a0a; +} + +.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-white strong { + color: inherit; +} + +.hero.is-white .title { + color: #0a0a0a; +} + +.hero.is-white .subtitle { + color: rgba(10, 10, 10, 0.9); +} + +.hero.is-white .subtitle a:not(.button), +.hero.is-white .subtitle strong { + color: #0a0a0a; +} + +@media screen and (max-width: 1023px) { + .hero.is-white .navbar-menu { + background-color: white; + } +} + +.hero.is-white .navbar-item, +.hero.is-white .navbar-link { + color: rgba(10, 10, 10, 0.7); +} + +.hero.is-white a.navbar-item:hover, .hero.is-white a.navbar-item.is-active, +.hero.is-white .navbar-link:hover, +.hero.is-white .navbar-link.is-active { + background-color: #f2f2f2; + color: #0a0a0a; +} + +.hero.is-white .tabs a { + color: #0a0a0a; + opacity: 0.9; +} + +.hero.is-white .tabs a:hover { + opacity: 1; +} + +.hero.is-white .tabs li.is-active a { + opacity: 1; +} + +.hero.is-white .tabs.is-boxed a, .hero.is-white .tabs.is-toggle a { + color: #0a0a0a; +} + +.hero.is-white .tabs.is-boxed a:hover, .hero.is-white .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-white .tabs.is-boxed li.is-active a, .hero.is-white .tabs.is-boxed li.is-active a:hover, .hero.is-white .tabs.is-toggle li.is-active a, .hero.is-white .tabs.is-toggle li.is-active a:hover { + background-color: #0a0a0a; + border-color: #0a0a0a; + color: white; +} + +.hero.is-white.is-bold { + background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-white.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #e6e6e6 0%, white 71%, white 100%); + } +} + +.hero.is-black { + background-color: #0a0a0a; + color: white; +} + +.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-black strong { + color: inherit; +} + +.hero.is-black .title { + color: white; +} + +.hero.is-black .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-black .subtitle a:not(.button), +.hero.is-black .subtitle strong { + color: white; +} + +@media screen and (max-width: 1023px) { + .hero.is-black .navbar-menu { + background-color: #0a0a0a; + } +} + +.hero.is-black .navbar-item, +.hero.is-black .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-black a.navbar-item:hover, .hero.is-black a.navbar-item.is-active, +.hero.is-black .navbar-link:hover, +.hero.is-black .navbar-link.is-active { + background-color: black; + color: white; +} + +.hero.is-black .tabs a { + color: white; + opacity: 0.9; +} + +.hero.is-black .tabs a:hover { + opacity: 1; +} + +.hero.is-black .tabs li.is-active a { + opacity: 1; +} + +.hero.is-black .tabs.is-boxed a, .hero.is-black .tabs.is-toggle a { + color: white; +} + +.hero.is-black .tabs.is-boxed a:hover, .hero.is-black .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-black .tabs.is-boxed li.is-active a, .hero.is-black .tabs.is-boxed li.is-active a:hover, .hero.is-black .tabs.is-toggle li.is-active a, .hero.is-black .tabs.is-toggle li.is-active a:hover { + background-color: white; + border-color: white; + color: #0a0a0a; +} + +.hero.is-black.is-bold { + background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-black.is-bold .navbar-menu { + background-image: linear-gradient(141deg, black 0%, #0a0a0a 71%, #181616 100%); + } +} + +.hero.is-light { + background-color: whitesmoke; + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-light strong { + color: inherit; +} + +.hero.is-light .title { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-light .subtitle { + color: rgba(0, 0, 0, 0.9); +} + +.hero.is-light .subtitle a:not(.button), +.hero.is-light .subtitle strong { + color: rgba(0, 0, 0, 0.7); +} + +@media screen and (max-width: 1023px) { + .hero.is-light .navbar-menu { + background-color: whitesmoke; + } +} + +.hero.is-light .navbar-item, +.hero.is-light .navbar-link { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-light a.navbar-item:hover, .hero.is-light a.navbar-item.is-active, +.hero.is-light .navbar-link:hover, +.hero.is-light .navbar-link.is-active { + background-color: #e8e8e8; + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-light .tabs a { + color: rgba(0, 0, 0, 0.7); + opacity: 0.9; +} + +.hero.is-light .tabs a:hover { + opacity: 1; +} + +.hero.is-light .tabs li.is-active a { + opacity: 1; +} + +.hero.is-light .tabs.is-boxed a, .hero.is-light .tabs.is-toggle a { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-light .tabs.is-boxed a:hover, .hero.is-light .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-light .tabs.is-boxed li.is-active a, .hero.is-light .tabs.is-boxed li.is-active a:hover, .hero.is-light .tabs.is-toggle li.is-active a, .hero.is-light .tabs.is-toggle li.is-active a:hover { + background-color: rgba(0, 0, 0, 0.7); + border-color: rgba(0, 0, 0, 0.7); + color: whitesmoke; +} + +.hero.is-light.is-bold { + background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-light.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #dfd8d9 0%, whitesmoke 71%, white 100%); + } +} + +.hero.is-dark { + background-color: #363636; + color: #fff; +} + +.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-dark strong { + color: inherit; +} + +.hero.is-dark .title { + color: #fff; +} + +.hero.is-dark .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-dark .subtitle a:not(.button), +.hero.is-dark .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-dark .navbar-menu { + background-color: #363636; + } +} + +.hero.is-dark .navbar-item, +.hero.is-dark .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-dark a.navbar-item:hover, .hero.is-dark a.navbar-item.is-active, +.hero.is-dark .navbar-link:hover, +.hero.is-dark .navbar-link.is-active { + background-color: #292929; + color: #fff; +} + +.hero.is-dark .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-dark .tabs a:hover { + opacity: 1; +} + +.hero.is-dark .tabs li.is-active a { + opacity: 1; +} + +.hero.is-dark .tabs.is-boxed a, .hero.is-dark .tabs.is-toggle a { + color: #fff; +} + +.hero.is-dark .tabs.is-boxed a:hover, .hero.is-dark .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-dark .tabs.is-boxed li.is-active a, .hero.is-dark .tabs.is-boxed li.is-active a:hover, .hero.is-dark .tabs.is-toggle li.is-active a, .hero.is-dark .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #363636; +} + +.hero.is-dark.is-bold { + background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-dark.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%); + } +} + +.hero.is-primary { + background-color: #00d1b2; + color: #fff; +} + +.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-primary strong { + color: inherit; +} + +.hero.is-primary .title { + color: #fff; +} + +.hero.is-primary .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-primary .subtitle a:not(.button), +.hero.is-primary .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-primary .navbar-menu { + background-color: #00d1b2; + } +} + +.hero.is-primary .navbar-item, +.hero.is-primary .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-primary a.navbar-item:hover, .hero.is-primary a.navbar-item.is-active, +.hero.is-primary .navbar-link:hover, +.hero.is-primary .navbar-link.is-active { + background-color: #00b89c; + color: #fff; +} + +.hero.is-primary .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-primary .tabs a:hover { + opacity: 1; +} + +.hero.is-primary .tabs li.is-active a { + opacity: 1; +} + +.hero.is-primary .tabs.is-boxed a, .hero.is-primary .tabs.is-toggle a { + color: #fff; +} + +.hero.is-primary .tabs.is-boxed a:hover, .hero.is-primary .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-primary .tabs.is-boxed li.is-active a, .hero.is-primary .tabs.is-boxed li.is-active a:hover, .hero.is-primary .tabs.is-toggle li.is-active a, .hero.is-primary .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #00d1b2; +} + +.hero.is-primary.is-bold { + background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-primary.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #009e6c 0%, #00d1b2 71%, #00e7eb 100%); + } +} + +.hero.is-link { + background-color: #3273dc; + color: #fff; +} + +.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-link strong { + color: inherit; +} + +.hero.is-link .title { + color: #fff; +} + +.hero.is-link .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-link .subtitle a:not(.button), +.hero.is-link .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-link .navbar-menu { + background-color: #3273dc; + } +} + +.hero.is-link .navbar-item, +.hero.is-link .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-link a.navbar-item:hover, .hero.is-link a.navbar-item.is-active, +.hero.is-link .navbar-link:hover, +.hero.is-link .navbar-link.is-active { + background-color: #2366d1; + color: #fff; +} + +.hero.is-link .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-link .tabs a:hover { + opacity: 1; +} + +.hero.is-link .tabs li.is-active a { + opacity: 1; +} + +.hero.is-link .tabs.is-boxed a, .hero.is-link .tabs.is-toggle a { + color: #fff; +} + +.hero.is-link .tabs.is-boxed a:hover, .hero.is-link .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-link .tabs.is-boxed li.is-active a, .hero.is-link .tabs.is-boxed li.is-active a:hover, .hero.is-link .tabs.is-toggle li.is-active a, .hero.is-link .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #3273dc; +} + +.hero.is-link.is-bold { + background-image: linear-gradient(141deg, #1577c6 0%, #3273dc 71%, #4366e5 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-link.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #1577c6 0%, #3273dc 71%, #4366e5 100%); + } +} + +.hero.is-info { + background-color: #3298dc; + color: #fff; +} + +.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-info strong { + color: inherit; +} + +.hero.is-info .title { + color: #fff; +} + +.hero.is-info .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-info .subtitle a:not(.button), +.hero.is-info .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-info .navbar-menu { + background-color: #3298dc; + } +} + +.hero.is-info .navbar-item, +.hero.is-info .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-info a.navbar-item:hover, .hero.is-info a.navbar-item.is-active, +.hero.is-info .navbar-link:hover, +.hero.is-info .navbar-link.is-active { + background-color: #238cd1; + color: #fff; +} + +.hero.is-info .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-info .tabs a:hover { + opacity: 1; +} + +.hero.is-info .tabs li.is-active a { + opacity: 1; +} + +.hero.is-info .tabs.is-boxed a, .hero.is-info .tabs.is-toggle a { + color: #fff; +} + +.hero.is-info .tabs.is-boxed a:hover, .hero.is-info .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-info .tabs.is-boxed li.is-active a, .hero.is-info .tabs.is-boxed li.is-active a:hover, .hero.is-info .tabs.is-toggle li.is-active a, .hero.is-info .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #3298dc; +} + +.hero.is-info.is-bold { + background-image: linear-gradient(141deg, #159dc6 0%, #3298dc 71%, #4389e5 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-info.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #159dc6 0%, #3298dc 71%, #4389e5 100%); + } +} + +.hero.is-success { + background-color: #48c774; + color: #fff; +} + +.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-success strong { + color: inherit; +} + +.hero.is-success .title { + color: #fff; +} + +.hero.is-success .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-success .subtitle a:not(.button), +.hero.is-success .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-success .navbar-menu { + background-color: #48c774; + } +} + +.hero.is-success .navbar-item, +.hero.is-success .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-success a.navbar-item:hover, .hero.is-success a.navbar-item.is-active, +.hero.is-success .navbar-link:hover, +.hero.is-success .navbar-link.is-active { + background-color: #3abb67; + color: #fff; +} + +.hero.is-success .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-success .tabs a:hover { + opacity: 1; +} + +.hero.is-success .tabs li.is-active a { + opacity: 1; +} + +.hero.is-success .tabs.is-boxed a, .hero.is-success .tabs.is-toggle a { + color: #fff; +} + +.hero.is-success .tabs.is-boxed a:hover, .hero.is-success .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-success .tabs.is-boxed li.is-active a, .hero.is-success .tabs.is-boxed li.is-active a:hover, .hero.is-success .tabs.is-toggle li.is-active a, .hero.is-success .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #48c774; +} + +.hero.is-success.is-bold { + background-image: linear-gradient(141deg, #29b342 0%, #48c774 71%, #56d296 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-success.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #29b342 0%, #48c774 71%, #56d296 100%); + } +} + +.hero.is-warning { + background-color: #ffdd57; + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-warning strong { + color: inherit; +} + +.hero.is-warning .title { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning .subtitle { + color: rgba(0, 0, 0, 0.9); +} + +.hero.is-warning .subtitle a:not(.button), +.hero.is-warning .subtitle strong { + color: rgba(0, 0, 0, 0.7); +} + +@media screen and (max-width: 1023px) { + .hero.is-warning .navbar-menu { + background-color: #ffdd57; + } +} + +.hero.is-warning .navbar-item, +.hero.is-warning .navbar-link { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning a.navbar-item:hover, .hero.is-warning a.navbar-item.is-active, +.hero.is-warning .navbar-link:hover, +.hero.is-warning .navbar-link.is-active { + background-color: #ffd83d; + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning .tabs a { + color: rgba(0, 0, 0, 0.7); + opacity: 0.9; +} + +.hero.is-warning .tabs a:hover { + opacity: 1; +} + +.hero.is-warning .tabs li.is-active a { + opacity: 1; +} + +.hero.is-warning .tabs.is-boxed a, .hero.is-warning .tabs.is-toggle a { + color: rgba(0, 0, 0, 0.7); +} + +.hero.is-warning .tabs.is-boxed a:hover, .hero.is-warning .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-warning .tabs.is-boxed li.is-active a, .hero.is-warning .tabs.is-boxed li.is-active a:hover, .hero.is-warning .tabs.is-toggle li.is-active a, .hero.is-warning .tabs.is-toggle li.is-active a:hover { + background-color: rgba(0, 0, 0, 0.7); + border-color: rgba(0, 0, 0, 0.7); + color: #ffdd57; +} + +.hero.is-warning.is-bold { + background-image: linear-gradient(141deg, #ffaf24 0%, #ffdd57 71%, #fffa70 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-warning.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #ffaf24 0%, #ffdd57 71%, #fffa70 100%); + } +} + +.hero.is-danger { + background-color: #f14668; + color: #fff; +} + +.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current), +.hero.is-danger strong { + color: inherit; +} + +.hero.is-danger .title { + color: #fff; +} + +.hero.is-danger .subtitle { + color: rgba(255, 255, 255, 0.9); +} + +.hero.is-danger .subtitle a:not(.button), +.hero.is-danger .subtitle strong { + color: #fff; +} + +@media screen and (max-width: 1023px) { + .hero.is-danger .navbar-menu { + background-color: #f14668; + } +} + +.hero.is-danger .navbar-item, +.hero.is-danger .navbar-link { + color: rgba(255, 255, 255, 0.7); +} + +.hero.is-danger a.navbar-item:hover, .hero.is-danger a.navbar-item.is-active, +.hero.is-danger .navbar-link:hover, +.hero.is-danger .navbar-link.is-active { + background-color: #ef2e55; + color: #fff; +} + +.hero.is-danger .tabs a { + color: #fff; + opacity: 0.9; +} + +.hero.is-danger .tabs a:hover { + opacity: 1; +} + +.hero.is-danger .tabs li.is-active a { + opacity: 1; +} + +.hero.is-danger .tabs.is-boxed a, .hero.is-danger .tabs.is-toggle a { + color: #fff; +} + +.hero.is-danger .tabs.is-boxed a:hover, .hero.is-danger .tabs.is-toggle a:hover { + background-color: rgba(10, 10, 10, 0.1); +} + +.hero.is-danger .tabs.is-boxed li.is-active a, .hero.is-danger .tabs.is-boxed li.is-active a:hover, .hero.is-danger .tabs.is-toggle li.is-active a, .hero.is-danger .tabs.is-toggle li.is-active a:hover { + background-color: #fff; + border-color: #fff; + color: #f14668; +} + +.hero.is-danger.is-bold { + background-image: linear-gradient(141deg, #fa0a62 0%, #f14668 71%, #f7595f 100%); +} + +@media screen and (max-width: 768px) { + .hero.is-danger.is-bold .navbar-menu { + background-image: linear-gradient(141deg, #fa0a62 0%, #f14668 71%, #f7595f 100%); + } +} + +.hero.is-small .hero-body { + padding: 1.5rem; +} + +@media screen and (min-width: 769px), print { + .hero.is-medium .hero-body { + padding: 9rem 1.5rem; + } +} + +@media screen and (min-width: 769px), print { + .hero.is-large .hero-body { + padding: 18rem 1.5rem; + } +} + +.hero.is-halfheight .hero-body, .hero.is-fullheight .hero-body, .hero.is-fullheight-with-navbar .hero-body { + align-items: center; + display: flex; +} + +.hero.is-halfheight .hero-body > .container, .hero.is-fullheight .hero-body > .container, .hero.is-fullheight-with-navbar .hero-body > .container { + flex-grow: 1; + flex-shrink: 1; +} + +.hero.is-halfheight { + min-height: 50vh; +} + +.hero.is-fullheight { + min-height: 100vh; +} + +.hero-video { + overflow: hidden; +} + +.hero-video video { + left: 50%; + min-height: 100%; + min-width: 100%; + position: absolute; + top: 50%; + transform: translate3d(-50%, -50%, 0); +} + +.hero-video.is-transparent { + opacity: 0.3; +} + +@media screen and (max-width: 768px) { + .hero-video { + display: none; + } +} + +.hero-buttons { + margin-top: 1.5rem; +} + +@media screen and (max-width: 768px) { + .hero-buttons .button { + display: flex; + } + .hero-buttons .button:not(:last-child) { + margin-bottom: 0.75rem; + } +} + +@media screen and (min-width: 769px), print { + .hero-buttons { + display: flex; + justify-content: center; + } + .hero-buttons .button:not(:last-child) { + margin-right: 1.5rem; + } +} + +.hero-head, +.hero-foot { + flex-grow: 0; + flex-shrink: 0; +} + +.hero-body { + flex-grow: 1; + flex-shrink: 0; + padding: 3rem 1.5rem; +} + +.section { + padding: 3rem 1.5rem; +} + +@media screen and (min-width: 1024px) { + .section.is-medium { + padding: 9rem 1.5rem; + } + .section.is-large { + padding: 18rem 1.5rem; + } +} + +.footer { + background-color: #fafafa; + padding: 3rem 1.5rem 6rem; +} +/*# sourceMappingURL=bulma.css.map */ \ No newline at end of file diff --git a/fedcode/static/css/bulma.css.ABOUT b/fedcode/static/css/bulma.css.ABOUT new file mode 100644 index 0000000..27d7e11 --- /dev/null +++ b/fedcode/static/css/bulma.css.ABOUT @@ -0,0 +1,14 @@ +about_resource: bulma.css +version: v0.9.0 +download_url: https://raw.githubusercontent.com/jgthms/bulma/891fb0677e74190dc6259fe4677eab2bd8a57ac1/css/bulma.css + +name: bulma css +homepage_url: https://github.com/jgthms/bulma +owner: Jeremy Thomas +author: Jeremy Thomas +notes: This is the minified version of Bulma CSS framework. + +license: mit +license_file: bulma.css.LICENSE + +copyright: Code copyright 2020 Jeremy Thomas. Code released under the MIT license. \ No newline at end of file diff --git a/fedcode/static/css/bulma.css.LICENSE b/fedcode/static/css/bulma.css.LICENSE new file mode 100644 index 0000000..04ab9e0 --- /dev/null +++ b/fedcode/static/css/bulma.css.LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Jeremy Thomas + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/fedcode/static/css/custom.css b/fedcode/static/css/custom.css new file mode 100644 index 0000000..6699d89 --- /dev/null +++ b/fedcode/static/css/custom.css @@ -0,0 +1,371 @@ +tab.Site { + display: flex; + min-height: 100vh; + flex-direction: column; +} + +.Site-content { + flex: 1; +} + +.nexb-orange { + color: #f7bf3c; +} + +.container.max-desktop-width { + max-width: 960px; +} + +body { + display: flex; + min-height: 100vh; + flex-direction: column; +} + +a { + color: #0066ff; + text-decoration: none; +} + +a:visited { + color: #0066ff; + text-decoration: none; +} + +a:hover { + color: #000000; + text-decoration: none; +} + +a { + font-weight: 400; +} + +a.button.paging { + color: #0066ff; +} + +a.button.paging:hover { + color: #000000; + text-decoration: none; +} + +a.button.paging:visited { + color: #0066ff; +} + +.button.is-link { + background-color: #485fc7; + border-color: transparent; + color: #fff; +} + +.container.is-fullheight { + min-height: 100vh; + flex: 1; + display: flex; + flex-direction: column; +} + +.footer { + background-color: #ffffff; + padding: 10px 10px 20px 10px; + border-top: solid 1px #000000; + font-size: 14px; + /* This keeps the footer at the bottom of a "short" page. */ + margin-top: auto; +} + +@media screen and (min-width: 1024px) { + .footer { + width: 960px; + } +} + +.navbar.border-bottom-radius { + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; +} + +code { + padding-left: 30px; + color: #cd0000; + font-size: 14px; +} + +.inline-code { + padding-left: 0px; + color: #cd0000; + background-color: #ffffff; + border: 0; + padding: 0; + font-family: Consolas; +} + +/* start tabset */ + +#tab-content div, +#tab-content div>div { + display: none; +} + +#tab-content div.is-active, +#tab-content div.is-active>div, +#tab-content div.is-active>div>div, +#tab-content div.is-active>div>div>div, +#tab-content div.is-active>div>div>div>div { + display: block; + visibility: visible; +} + +#tab-content div { + border-bottom: 0; + margin-bottom: 50px; + padding-bottom: 50px; +} + +#tab-content .tab-nested-div { + border-bottom: 0; + margin-bottom: 0px; + padding-bottom: 0px; +} + +.tab-div { + border: 0; + background-color: #ffffff; + padding: 10px; +} + +.tabs.is-boxed ul { + padding-left: 20px; + border-color: #3298dc; +} + +.tabs li { + margin-left: 0px; + margin-right: 0px; +} + +.tabs.is-boxed li a { + border-top-width: 3px; +} + +.tabs:not(:last-child) { + margin-bottom: 0px; +} + +.tabs.is-boxed li a:hover { + border: solid 1px #e8e8e8; + border-top-width: 3px; + background-color: #ffffff; + border-color: #e8e8e8; + border-bottom-color: #3298dc; +} + +.tabs.is-boxed li.is-active a, +.tabs.is-boxed li.is-active a:hover { + background-color: white; + border-top: solid 3px #3298dc; + border-bottom-color: transparent !important; + color: #000000; + border-color: #3298dc; +} + +/* end tabset */ + +.table.vcio-table td { + border: 0; +} + +.table th { + border-color: #000000; +} + +.table.gray-header-border th { + border-color: #dbdbdb; +} + +.table td { + word-wrap: break-word; + /* 8/24/2022 Wednesday 4:56:57 PM. We need this for just 1 table as I recall, displaying some sort of data with few/no word breaks + but this messes up the look of columns that need a word-break wrap + TODO: identify and create separate CSS class for that table */ + /* word-break: break-all; */ +} + +.wrap-strings { + word-break: break-all; +} + +.two-col-left { + width: 160px; + text-align: right !important; + font-weight: bold; + padding-right: 20px !important; + line-height: 20px; + border: solid 1px #e8e8e8 !important; +} + +.two-col-right { + border: solid 1px #e8e8e8 !important; + line-height: 20px; +} + +pre { + font-family: Consolas !important; + font-size: 13px; + color: #cc0000; + background-color: #f8f8f8; + border: solid 1px #e8e8e8; + border-radius: 5px; + overflow: visible; + white-space: pre-wrap; + margin: 10px 0px 0px 0px; + padding: 12px; + display: block; +} + +ul { + list-style-type: square; +} + +ul li { + background-repeat: no-repeat; + margin-left: 20px; +} + +.is-clipped-list ul { + list-style-type: none; + padding-left: 0px; + margin-left: 0px; + margin-top: 0px; +} + +.is-clipped-list ul li { + margin-left: 0px; + line-height: 18px; +} + +.tag:not(body).is-search-label-left { + box-shadow: 5px 5px 5px #cccccc; + border: solid 1px #b8b8b8; + font-weight: bold; +} + +.tag:not(body).is-search-label-right { + box-shadow: 5px 5px 5px #cccccc; + border: solid 1px #b8b8b8; + border-left: 0; +} + +.message a:not(.button):not(.tag):not(.dropdown-item) { + color: #0066ff; + text-decoration: none; +} + +.message a:not(.button):not(.tag):not(.dropdown-item):hover { + color: #0066ff; + text-decoration: underline; +} + +.message.is-info { + background-color: #ffffff; + border: 0; + box-shadow: 0 0.5em 1em -0.125em #e8e8e8, 0 0 0 1px #e8e8e8; +} + +.message.is-info .message-header { + background-color: #3e8ed0; + color: #fff; +} + +.message.is-info .message-body { + border-color: #3298dc; + color: #000000; +} + +/* This is missing from our local bulma.css file, and is needed for the page-bottom pagination */ +.pagination-list li { + list-style: none; + margin: 0; +} + +.small_page_button { + border: solid 1px #f2f2f2; + border-radius: 3px; + padding: 0px 6px 0px 6px; + background-color: #f8f8f8; + color: #cccccc; + font-size: 12px; +} + +a.small_page_button { + border-color: #99c2ff; + background-color: #ffffff; + color: #0066ff; +} + +.page_arrow_spacing { + padding: 0px 3px 0px 3px; +} + +.panel:not(:last-child).panel-header-only { + margin-bottom: 1.0rem; +} + +.column.skinny { + padding: 0.10rem; + line-height: 17px; + background-color: #ffffff; + border: solid 1px #e8e8e8; + font-size: 14px; +} + +.dropdown-instructions-width { + width: 600px; +} + +.dropdown-instructions-box-shadow { + box-shadow: 0px 8px 16px 0px #808080; +} + +.width-100-pct { + width: 100%; +} + +.search-alert { + border: solid 1px #ff9999; + padding: 20px; + margin-top: 20px; + background-color: #ffffff; + color: #ff0000; + z-index: 10; +} + +.navbar-hover-div { + border: 0; + box-shadow: 0px 8px 16px 0px #808080; + min-width: 13rem; + padding: 0px; +} + +.details-container { + border: solid 1px #e8e8e8; + border: 0; + border-radius: 6px; + box-shadow: 0 0.5em 1em -0.125em rgb(10 10 10 / 10%), 0 0px 0 1px rgb(10 10 10 / 2%); +} + +.about-hover-div { + width: 500px; +} + +.fa_link_custom { + font-size: 10px !important; + vertical-align: super; + margin-left: 2px; +} + +span.tag.custom { + margin: 0px 0px 6px 10px; +} \ No newline at end of file diff --git a/fedcode/static/css/font-awesome.css b/fedcode/static/css/font-awesome.css new file mode 100644 index 0000000..eab1cbb --- /dev/null +++ b/fedcode/static/css/font-awesome.css @@ -0,0 +1,2337 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */ +/* FONT PATH + * -------------------------- */ +@font-face { + font-family: 'FontAwesome'; + src: url('fontawesome-webfont.eot?v=4.7.0'); + src: url('fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('fontawesome-webfont.woff?v=4.7.0') format('woff'), url('fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); + font-weight: normal; + font-style: normal; +} +.fa { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +/* makes the font 33% larger relative to the icon container */ +.fa-lg { + font-size: 1.33333333em; + line-height: 0.75em; + vertical-align: -15%; +} +.fa-2x { + font-size: 2em; +} +.fa-3x { + font-size: 3em; +} +.fa-4x { + font-size: 4em; +} +.fa-5x { + font-size: 5em; +} +.fa-fw { + width: 1.28571429em; + text-align: center; +} +.fa-ul { + padding-left: 0; + margin-left: 2.14285714em; + list-style-type: none; +} +.fa-ul > li { + position: relative; +} +.fa-li { + position: absolute; + left: -2.14285714em; + width: 2.14285714em; + top: 0.14285714em; + text-align: center; +} +.fa-li.fa-lg { + left: -1.85714286em; +} +.fa-border { + padding: .2em .25em .15em; + border: solid 0.08em #eeeeee; + border-radius: .1em; +} +.fa-pull-left { + float: left; +} +.fa-pull-right { + float: right; +} +.fa.fa-pull-left { + margin-right: .3em; +} +.fa.fa-pull-right { + margin-left: .3em; +} +/* Deprecated as of 4.4.0 */ +.pull-right { + float: right; +} +.pull-left { + float: left; +} +.fa.pull-left { + margin-right: .3em; +} +.fa.pull-right { + margin-left: .3em; +} +.fa-spin { + -webkit-animation: fa-spin 2s infinite linear; + animation: fa-spin 2s infinite linear; +} +.fa-pulse { + -webkit-animation: fa-spin 1s infinite steps(8); + animation: fa-spin 1s infinite steps(8); +} +@-webkit-keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes fa-spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +.fa-rotate-90 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} +.fa-rotate-180 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); +} +.fa-rotate-270 { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; + -webkit-transform: rotate(270deg); + -ms-transform: rotate(270deg); + transform: rotate(270deg); +} +.fa-flip-horizontal { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; + -webkit-transform: scale(-1, 1); + -ms-transform: scale(-1, 1); + transform: scale(-1, 1); +} +.fa-flip-vertical { + -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; + -webkit-transform: scale(1, -1); + -ms-transform: scale(1, -1); + transform: scale(1, -1); +} +:root .fa-rotate-90, +:root .fa-rotate-180, +:root .fa-rotate-270, +:root .fa-flip-horizontal, +:root .fa-flip-vertical { + filter: none; +} +.fa-stack { + position: relative; + display: inline-block; + width: 2em; + height: 2em; + line-height: 2em; + vertical-align: middle; +} +.fa-stack-1x, +.fa-stack-2x { + position: absolute; + left: 0; + width: 100%; + text-align: center; +} +.fa-stack-1x { + line-height: inherit; +} +.fa-stack-2x { + font-size: 2em; +} +.fa-inverse { + color: #ffffff; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.fa-glass:before { + content: "\f000"; +} +.fa-music:before { + content: "\f001"; +} +.fa-search:before { + content: "\f002"; +} +.fa-envelope-o:before { + content: "\f003"; +} +.fa-heart:before { + content: "\f004"; +} +.fa-star:before { + content: "\f005"; +} +.fa-star-o:before { + content: "\f006"; +} +.fa-user:before { + content: "\f007"; +} +.fa-film:before { + content: "\f008"; +} +.fa-th-large:before { + content: "\f009"; +} +.fa-th:before { + content: "\f00a"; +} +.fa-th-list:before { + content: "\f00b"; +} +.fa-check:before { + content: "\f00c"; +} +.fa-remove:before, +.fa-close:before, +.fa-times:before { + content: "\f00d"; +} +.fa-search-plus:before { + content: "\f00e"; +} +.fa-search-minus:before { + content: "\f010"; +} +.fa-power-off:before { + content: "\f011"; +} +.fa-signal:before { + content: "\f012"; +} +.fa-gear:before, +.fa-cog:before { + content: "\f013"; +} +.fa-trash-o:before { + content: "\f014"; +} +.fa-home:before { + content: "\f015"; +} +.fa-file-o:before { + content: "\f016"; +} +.fa-clock-o:before { + content: "\f017"; +} +.fa-road:before { + content: "\f018"; +} +.fa-download:before { + content: "\f019"; +} +.fa-arrow-circle-o-down:before { + content: "\f01a"; +} +.fa-arrow-circle-o-up:before { + content: "\f01b"; +} +.fa-inbox:before { + content: "\f01c"; +} +.fa-play-circle-o:before { + content: "\f01d"; +} +.fa-rotate-right:before, +.fa-repeat:before { + content: "\f01e"; +} +.fa-refresh:before { + content: "\f021"; +} +.fa-list-alt:before { + content: "\f022"; +} +.fa-lock:before { + content: "\f023"; +} +.fa-flag:before { + content: "\f024"; +} +.fa-headphones:before { + content: "\f025"; +} +.fa-volume-off:before { + content: "\f026"; +} +.fa-volume-down:before { + content: "\f027"; +} +.fa-volume-up:before { + content: "\f028"; +} +.fa-qrcode:before { + content: "\f029"; +} +.fa-barcode:before { + content: "\f02a"; +} +.fa-tag:before { + content: "\f02b"; +} +.fa-tags:before { + content: "\f02c"; +} +.fa-book:before { + content: "\f02d"; +} +.fa-bookmark:before { + content: "\f02e"; +} +.fa-print:before { + content: "\f02f"; +} +.fa-camera:before { + content: "\f030"; +} +.fa-font:before { + content: "\f031"; +} +.fa-bold:before { + content: "\f032"; +} +.fa-italic:before { + content: "\f033"; +} +.fa-text-height:before { + content: "\f034"; +} +.fa-text-width:before { + content: "\f035"; +} +.fa-align-left:before { + content: "\f036"; +} +.fa-align-center:before { + content: "\f037"; +} +.fa-align-right:before { + content: "\f038"; +} +.fa-align-justify:before { + content: "\f039"; +} +.fa-list:before { + content: "\f03a"; +} +.fa-dedent:before, +.fa-outdent:before { + content: "\f03b"; +} +.fa-indent:before { + content: "\f03c"; +} +.fa-video-camera:before { + content: "\f03d"; +} +.fa-photo:before, +.fa-image:before, +.fa-picture-o:before { + content: "\f03e"; +} +.fa-pencil:before { + content: "\f040"; +} +.fa-map-marker:before { + content: "\f041"; +} +.fa-adjust:before { + content: "\f042"; +} +.fa-tint:before { + content: "\f043"; +} +.fa-edit:before, +.fa-pencil-square-o:before { + content: "\f044"; +} +.fa-share-square-o:before { + content: "\f045"; +} +.fa-check-square-o:before { + content: "\f046"; +} +.fa-arrows:before { + content: "\f047"; +} +.fa-step-backward:before { + content: "\f048"; +} +.fa-fast-backward:before { + content: "\f049"; +} +.fa-backward:before { + content: "\f04a"; +} +.fa-play:before { + content: "\f04b"; +} +.fa-pause:before { + content: "\f04c"; +} +.fa-stop:before { + content: "\f04d"; +} +.fa-forward:before { + content: "\f04e"; +} +.fa-fast-forward:before { + content: "\f050"; +} +.fa-step-forward:before { + content: "\f051"; +} +.fa-eject:before { + content: "\f052"; +} +.fa-chevron-left:before { + content: "\f053"; +} +.fa-chevron-right:before { + content: "\f054"; +} +.fa-plus-circle:before { + content: "\f055"; +} +.fa-minus-circle:before { + content: "\f056"; +} +.fa-times-circle:before { + content: "\f057"; +} +.fa-check-circle:before { + content: "\f058"; +} +.fa-question-circle:before { + content: "\f059"; +} +.fa-info-circle:before { + content: "\f05a"; +} +.fa-crosshairs:before { + content: "\f05b"; +} +.fa-times-circle-o:before { + content: "\f05c"; +} +.fa-check-circle-o:before { + content: "\f05d"; +} +.fa-ban:before { + content: "\f05e"; +} +.fa-arrow-left:before { + content: "\f060"; +} +.fa-arrow-right:before { + content: "\f061"; +} +.fa-arrow-up:before { + content: "\f062"; +} +.fa-arrow-down:before { + content: "\f063"; +} +.fa-mail-forward:before, +.fa-share:before { + content: "\f064"; +} +.fa-expand:before { + content: "\f065"; +} +.fa-compress:before { + content: "\f066"; +} +.fa-plus:before { + content: "\f067"; +} +.fa-minus:before { + content: "\f068"; +} +.fa-asterisk:before { + content: "\f069"; +} +.fa-exclamation-circle:before { + content: "\f06a"; +} +.fa-gift:before { + content: "\f06b"; +} +.fa-leaf:before { + content: "\f06c"; +} +.fa-fire:before { + content: "\f06d"; +} +.fa-eye:before { + content: "\f06e"; +} +.fa-eye-slash:before { + content: "\f070"; +} +.fa-warning:before, +.fa-exclamation-triangle:before { + content: "\f071"; +} +.fa-plane:before { + content: "\f072"; +} +.fa-calendar:before { + content: "\f073"; +} +.fa-random:before { + content: "\f074"; +} +.fa-comment:before { + content: "\f075"; +} +.fa-magnet:before { + content: "\f076"; +} +.fa-chevron-up:before { + content: "\f077"; +} +.fa-chevron-down:before { + content: "\f078"; +} +.fa-retweet:before { + content: "\f079"; +} +.fa-shopping-cart:before { + content: "\f07a"; +} +.fa-folder:before { + content: "\f07b"; +} +.fa-folder-open:before { + content: "\f07c"; +} +.fa-arrows-v:before { + content: "\f07d"; +} +.fa-arrows-h:before { + content: "\f07e"; +} +.fa-bar-chart-o:before, +.fa-bar-chart:before { + content: "\f080"; +} +.fa-twitter-square:before { + content: "\f081"; +} +.fa-facebook-square:before { + content: "\f082"; +} +.fa-camera-retro:before { + content: "\f083"; +} +.fa-key:before { + content: "\f084"; +} +.fa-gears:before, +.fa-cogs:before { + content: "\f085"; +} +.fa-comments:before { + content: "\f086"; +} +.fa-thumbs-o-up:before { + content: "\f087"; +} +.fa-thumbs-o-down:before { + content: "\f088"; +} +.fa-star-half:before { + content: "\f089"; +} +.fa-heart-o:before { + content: "\f08a"; +} +.fa-sign-out:before { + content: "\f08b"; +} +.fa-linkedin-square:before { + content: "\f08c"; +} +.fa-thumb-tack:before { + content: "\f08d"; +} +.fa-external-link:before { + content: "\f08e"; +} +.fa-sign-in:before { + content: "\f090"; +} +.fa-trophy:before { + content: "\f091"; +} +.fa-github-square:before { + content: "\f092"; +} +.fa-upload:before { + content: "\f093"; +} +.fa-lemon-o:before { + content: "\f094"; +} +.fa-phone:before { + content: "\f095"; +} +.fa-square-o:before { + content: "\f096"; +} +.fa-bookmark-o:before { + content: "\f097"; +} +.fa-phone-square:before { + content: "\f098"; +} +.fa-twitter:before { + content: "\f099"; +} +.fa-facebook-f:before, +.fa-facebook:before { + content: "\f09a"; +} +.fa-github:before { + content: "\f09b"; +} +.fa-unlock:before { + content: "\f09c"; +} +.fa-credit-card:before { + content: "\f09d"; +} +.fa-feed:before, +.fa-rss:before { + content: "\f09e"; +} +.fa-hdd-o:before { + content: "\f0a0"; +} +.fa-bullhorn:before { + content: "\f0a1"; +} +.fa-bell:before { + content: "\f0f3"; +} +.fa-certificate:before { + content: "\f0a3"; +} +.fa-hand-o-right:before { + content: "\f0a4"; +} +.fa-hand-o-left:before { + content: "\f0a5"; +} +.fa-hand-o-up:before { + content: "\f0a6"; +} +.fa-hand-o-down:before { + content: "\f0a7"; +} +.fa-arrow-circle-left:before { + content: "\f0a8"; +} +.fa-arrow-circle-right:before { + content: "\f0a9"; +} +.fa-arrow-circle-up:before { + content: "\f0aa"; +} +.fa-arrow-circle-down:before { + content: "\f0ab"; +} +.fa-globe:before { + content: "\f0ac"; +} +.fa-wrench:before { + content: "\f0ad"; +} +.fa-tasks:before { + content: "\f0ae"; +} +.fa-filter:before { + content: "\f0b0"; +} +.fa-briefcase:before { + content: "\f0b1"; +} +.fa-arrows-alt:before { + content: "\f0b2"; +} +.fa-group:before, +.fa-users:before { + content: "\f0c0"; +} +.fa-chain:before, +.fa-link:before { + content: "\f0c1"; +} +.fa-cloud:before { + content: "\f0c2"; +} +.fa-flask:before { + content: "\f0c3"; +} +.fa-cut:before, +.fa-scissors:before { + content: "\f0c4"; +} +.fa-copy:before, +.fa-files-o:before { + content: "\f0c5"; +} +.fa-paperclip:before { + content: "\f0c6"; +} +.fa-save:before, +.fa-floppy-o:before { + content: "\f0c7"; +} +.fa-square:before { + content: "\f0c8"; +} +.fa-navicon:before, +.fa-reorder:before, +.fa-bars:before { + content: "\f0c9"; +} +.fa-list-ul:before { + content: "\f0ca"; +} +.fa-list-ol:before { + content: "\f0cb"; +} +.fa-strikethrough:before { + content: "\f0cc"; +} +.fa-underline:before { + content: "\f0cd"; +} +.fa-table:before { + content: "\f0ce"; +} +.fa-magic:before { + content: "\f0d0"; +} +.fa-truck:before { + content: "\f0d1"; +} +.fa-pinterest:before { + content: "\f0d2"; +} +.fa-pinterest-square:before { + content: "\f0d3"; +} +.fa-google-plus-square:before { + content: "\f0d4"; +} +.fa-google-plus:before { + content: "\f0d5"; +} +.fa-money:before { + content: "\f0d6"; +} +.fa-caret-down:before { + content: "\f0d7"; +} +.fa-caret-up:before { + content: "\f0d8"; +} +.fa-caret-left:before { + content: "\f0d9"; +} +.fa-caret-right:before { + content: "\f0da"; +} +.fa-columns:before { + content: "\f0db"; +} +.fa-unsorted:before, +.fa-sort:before { + content: "\f0dc"; +} +.fa-sort-down:before, +.fa-sort-desc:before { + content: "\f0dd"; +} +.fa-sort-up:before, +.fa-sort-asc:before { + content: "\f0de"; +} +.fa-envelope:before { + content: "\f0e0"; +} +.fa-linkedin:before { + content: "\f0e1"; +} +.fa-rotate-left:before, +.fa-undo:before { + content: "\f0e2"; +} +.fa-legal:before, +.fa-gavel:before { + content: "\f0e3"; +} +.fa-dashboard:before, +.fa-tachometer:before { + content: "\f0e4"; +} +.fa-comment-o:before { + content: "\f0e5"; +} +.fa-comments-o:before { + content: "\f0e6"; +} +.fa-flash:before, +.fa-bolt:before { + content: "\f0e7"; +} +.fa-sitemap:before { + content: "\f0e8"; +} +.fa-umbrella:before { + content: "\f0e9"; +} +.fa-paste:before, +.fa-clipboard:before { + content: "\f0ea"; +} +.fa-lightbulb-o:before { + content: "\f0eb"; +} +.fa-exchange:before { + content: "\f0ec"; +} +.fa-cloud-download:before { + content: "\f0ed"; +} +.fa-cloud-upload:before { + content: "\f0ee"; +} +.fa-user-md:before { + content: "\f0f0"; +} +.fa-stethoscope:before { + content: "\f0f1"; +} +.fa-suitcase:before { + content: "\f0f2"; +} +.fa-bell-o:before { + content: "\f0a2"; +} +.fa-coffee:before { + content: "\f0f4"; +} +.fa-cutlery:before { + content: "\f0f5"; +} +.fa-file-text-o:before { + content: "\f0f6"; +} +.fa-building-o:before { + content: "\f0f7"; +} +.fa-hospital-o:before { + content: "\f0f8"; +} +.fa-ambulance:before { + content: "\f0f9"; +} +.fa-medkit:before { + content: "\f0fa"; +} +.fa-fighter-jet:before { + content: "\f0fb"; +} +.fa-beer:before { + content: "\f0fc"; +} +.fa-h-square:before { + content: "\f0fd"; +} +.fa-plus-square:before { + content: "\f0fe"; +} +.fa-angle-double-left:before { + content: "\f100"; +} +.fa-angle-double-right:before { + content: "\f101"; +} +.fa-angle-double-up:before { + content: "\f102"; +} +.fa-angle-double-down:before { + content: "\f103"; +} +.fa-angle-left:before { + content: "\f104"; +} +.fa-angle-right:before { + content: "\f105"; +} +.fa-angle-up:before { + content: "\f106"; +} +.fa-angle-down:before { + content: "\f107"; +} +.fa-desktop:before { + content: "\f108"; +} +.fa-laptop:before { + content: "\f109"; +} +.fa-tablet:before { + content: "\f10a"; +} +.fa-mobile-phone:before, +.fa-mobile:before { + content: "\f10b"; +} +.fa-circle-o:before { + content: "\f10c"; +} +.fa-quote-left:before { + content: "\f10d"; +} +.fa-quote-right:before { + content: "\f10e"; +} +.fa-spinner:before { + content: "\f110"; +} +.fa-circle:before { + content: "\f111"; +} +.fa-mail-reply:before, +.fa-reply:before { + content: "\f112"; +} +.fa-github-alt:before { + content: "\f113"; +} +.fa-folder-o:before { + content: "\f114"; +} +.fa-folder-open-o:before { + content: "\f115"; +} +.fa-smile-o:before { + content: "\f118"; +} +.fa-frown-o:before { + content: "\f119"; +} +.fa-meh-o:before { + content: "\f11a"; +} +.fa-gamepad:before { + content: "\f11b"; +} +.fa-keyboard-o:before { + content: "\f11c"; +} +.fa-flag-o:before { + content: "\f11d"; +} +.fa-flag-checkered:before { + content: "\f11e"; +} +.fa-terminal:before { + content: "\f120"; +} +.fa-code:before { + content: "\f121"; +} +.fa-mail-reply-all:before, +.fa-reply-all:before { + content: "\f122"; +} +.fa-star-half-empty:before, +.fa-star-half-full:before, +.fa-star-half-o:before { + content: "\f123"; +} +.fa-location-arrow:before { + content: "\f124"; +} +.fa-crop:before { + content: "\f125"; +} +.fa-code-fork:before { + content: "\f126"; +} +.fa-unlink:before, +.fa-chain-broken:before { + content: "\f127"; +} +.fa-question:before { + content: "\f128"; +} +.fa-info:before { + content: "\f129"; +} +.fa-exclamation:before { + content: "\f12a"; +} +.fa-superscript:before { + content: "\f12b"; +} +.fa-subscript:before { + content: "\f12c"; +} +.fa-eraser:before { + content: "\f12d"; +} +.fa-puzzle-piece:before { + content: "\f12e"; +} +.fa-microphone:before { + content: "\f130"; +} +.fa-microphone-slash:before { + content: "\f131"; +} +.fa-shield:before { + content: "\f132"; +} +.fa-calendar-o:before { + content: "\f133"; +} +.fa-fire-extinguisher:before { + content: "\f134"; +} +.fa-rocket:before { + content: "\f135"; +} +.fa-maxcdn:before { + content: "\f136"; +} +.fa-chevron-circle-left:before { + content: "\f137"; +} +.fa-chevron-circle-right:before { + content: "\f138"; +} +.fa-chevron-circle-up:before { + content: "\f139"; +} +.fa-chevron-circle-down:before { + content: "\f13a"; +} +.fa-html5:before { + content: "\f13b"; +} +.fa-css3:before { + content: "\f13c"; +} +.fa-anchor:before { + content: "\f13d"; +} +.fa-unlock-alt:before { + content: "\f13e"; +} +.fa-bullseye:before { + content: "\f140"; +} +.fa-ellipsis-h:before { + content: "\f141"; +} +.fa-ellipsis-v:before { + content: "\f142"; +} +.fa-rss-square:before { + content: "\f143"; +} +.fa-play-circle:before { + content: "\f144"; +} +.fa-ticket:before { + content: "\f145"; +} +.fa-minus-square:before { + content: "\f146"; +} +.fa-minus-square-o:before { + content: "\f147"; +} +.fa-level-up:before { + content: "\f148"; +} +.fa-level-down:before { + content: "\f149"; +} +.fa-check-square:before { + content: "\f14a"; +} +.fa-pencil-square:before { + content: "\f14b"; +} +.fa-external-link-square:before { + content: "\f14c"; +} +.fa-share-square:before { + content: "\f14d"; +} +.fa-compass:before { + content: "\f14e"; +} +.fa-toggle-down:before, +.fa-caret-square-o-down:before { + content: "\f150"; +} +.fa-toggle-up:before, +.fa-caret-square-o-up:before { + content: "\f151"; +} +.fa-toggle-right:before, +.fa-caret-square-o-right:before { + content: "\f152"; +} +.fa-euro:before, +.fa-eur:before { + content: "\f153"; +} +.fa-gbp:before { + content: "\f154"; +} +.fa-dollar:before, +.fa-usd:before { + content: "\f155"; +} +.fa-rupee:before, +.fa-inr:before { + content: "\f156"; +} +.fa-cny:before, +.fa-rmb:before, +.fa-yen:before, +.fa-jpy:before { + content: "\f157"; +} +.fa-ruble:before, +.fa-rouble:before, +.fa-rub:before { + content: "\f158"; +} +.fa-won:before, +.fa-krw:before { + content: "\f159"; +} +.fa-bitcoin:before, +.fa-btc:before { + content: "\f15a"; +} +.fa-file:before { + content: "\f15b"; +} +.fa-file-text:before { + content: "\f15c"; +} +.fa-sort-alpha-asc:before { + content: "\f15d"; +} +.fa-sort-alpha-desc:before { + content: "\f15e"; +} +.fa-sort-amount-asc:before { + content: "\f160"; +} +.fa-sort-amount-desc:before { + content: "\f161"; +} +.fa-sort-numeric-asc:before { + content: "\f162"; +} +.fa-sort-numeric-desc:before { + content: "\f163"; +} +.fa-thumbs-up:before { + content: "\f164"; +} +.fa-thumbs-down:before { + content: "\f165"; +} +.fa-youtube-square:before { + content: "\f166"; +} +.fa-youtube:before { + content: "\f167"; +} +.fa-xing:before { + content: "\f168"; +} +.fa-xing-square:before { + content: "\f169"; +} +.fa-youtube-play:before { + content: "\f16a"; +} +.fa-dropbox:before { + content: "\f16b"; +} +.fa-stack-overflow:before { + content: "\f16c"; +} +.fa-instagram:before { + content: "\f16d"; +} +.fa-flickr:before { + content: "\f16e"; +} +.fa-adn:before { + content: "\f170"; +} +.fa-bitbucket:before { + content: "\f171"; +} +.fa-bitbucket-square:before { + content: "\f172"; +} +.fa-tumblr:before { + content: "\f173"; +} +.fa-tumblr-square:before { + content: "\f174"; +} +.fa-long-arrow-down:before { + content: "\f175"; +} +.fa-long-arrow-up:before { + content: "\f176"; +} +.fa-long-arrow-left:before { + content: "\f177"; +} +.fa-long-arrow-right:before { + content: "\f178"; +} +.fa-apple:before { + content: "\f179"; +} +.fa-windows:before { + content: "\f17a"; +} +.fa-android:before { + content: "\f17b"; +} +.fa-linux:before { + content: "\f17c"; +} +.fa-dribbble:before { + content: "\f17d"; +} +.fa-skype:before { + content: "\f17e"; +} +.fa-foursquare:before { + content: "\f180"; +} +.fa-trello:before { + content: "\f181"; +} +.fa-female:before { + content: "\f182"; +} +.fa-male:before { + content: "\f183"; +} +.fa-gittip:before, +.fa-gratipay:before { + content: "\f184"; +} +.fa-sun-o:before { + content: "\f185"; +} +.fa-moon-o:before { + content: "\f186"; +} +.fa-archive:before { + content: "\f187"; +} +.fa-bug:before { + content: "\f188"; +} +.fa-vk:before { + content: "\f189"; +} +.fa-weibo:before { + content: "\f18a"; +} +.fa-renren:before { + content: "\f18b"; +} +.fa-pagelines:before { + content: "\f18c"; +} +.fa-stack-exchange:before { + content: "\f18d"; +} +.fa-arrow-circle-o-right:before { + content: "\f18e"; +} +.fa-arrow-circle-o-left:before { + content: "\f190"; +} +.fa-toggle-left:before, +.fa-caret-square-o-left:before { + content: "\f191"; +} +.fa-dot-circle-o:before { + content: "\f192"; +} +.fa-wheelchair:before { + content: "\f193"; +} +.fa-vimeo-square:before { + content: "\f194"; +} +.fa-turkish-lira:before, +.fa-try:before { + content: "\f195"; +} +.fa-plus-square-o:before { + content: "\f196"; +} +.fa-space-shuttle:before { + content: "\f197"; +} +.fa-slack:before { + content: "\f198"; +} +.fa-envelope-square:before { + content: "\f199"; +} +.fa-wordpress:before { + content: "\f19a"; +} +.fa-openid:before { + content: "\f19b"; +} +.fa-institution:before, +.fa-bank:before, +.fa-university:before { + content: "\f19c"; +} +.fa-mortar-board:before, +.fa-graduation-cap:before { + content: "\f19d"; +} +.fa-yahoo:before { + content: "\f19e"; +} +.fa-google:before { + content: "\f1a0"; +} +.fa-reddit:before { + content: "\f1a1"; +} +.fa-reddit-square:before { + content: "\f1a2"; +} +.fa-stumbleupon-circle:before { + content: "\f1a3"; +} +.fa-stumbleupon:before { + content: "\f1a4"; +} +.fa-delicious:before { + content: "\f1a5"; +} +.fa-digg:before { + content: "\f1a6"; +} +.fa-pied-piper-pp:before { + content: "\f1a7"; +} +.fa-pied-piper-alt:before { + content: "\f1a8"; +} +.fa-drupal:before { + content: "\f1a9"; +} +.fa-joomla:before { + content: "\f1aa"; +} +.fa-language:before { + content: "\f1ab"; +} +.fa-fax:before { + content: "\f1ac"; +} +.fa-building:before { + content: "\f1ad"; +} +.fa-child:before { + content: "\f1ae"; +} +.fa-paw:before { + content: "\f1b0"; +} +.fa-spoon:before { + content: "\f1b1"; +} +.fa-cube:before { + content: "\f1b2"; +} +.fa-cubes:before { + content: "\f1b3"; +} +.fa-behance:before { + content: "\f1b4"; +} +.fa-behance-square:before { + content: "\f1b5"; +} +.fa-steam:before { + content: "\f1b6"; +} +.fa-steam-square:before { + content: "\f1b7"; +} +.fa-recycle:before { + content: "\f1b8"; +} +.fa-automobile:before, +.fa-car:before { + content: "\f1b9"; +} +.fa-cab:before, +.fa-taxi:before { + content: "\f1ba"; +} +.fa-tree:before { + content: "\f1bb"; +} +.fa-spotify:before { + content: "\f1bc"; +} +.fa-deviantart:before { + content: "\f1bd"; +} +.fa-soundcloud:before { + content: "\f1be"; +} +.fa-database:before { + content: "\f1c0"; +} +.fa-file-pdf-o:before { + content: "\f1c1"; +} +.fa-file-word-o:before { + content: "\f1c2"; +} +.fa-file-excel-o:before { + content: "\f1c3"; +} +.fa-file-powerpoint-o:before { + content: "\f1c4"; +} +.fa-file-photo-o:before, +.fa-file-picture-o:before, +.fa-file-image-o:before { + content: "\f1c5"; +} +.fa-file-zip-o:before, +.fa-file-archive-o:before { + content: "\f1c6"; +} +.fa-file-sound-o:before, +.fa-file-audio-o:before { + content: "\f1c7"; +} +.fa-file-movie-o:before, +.fa-file-video-o:before { + content: "\f1c8"; +} +.fa-file-code-o:before { + content: "\f1c9"; +} +.fa-vine:before { + content: "\f1ca"; +} +.fa-codepen:before { + content: "\f1cb"; +} +.fa-jsfiddle:before { + content: "\f1cc"; +} +.fa-life-bouy:before, +.fa-life-buoy:before, +.fa-life-saver:before, +.fa-support:before, +.fa-life-ring:before { + content: "\f1cd"; +} +.fa-circle-o-notch:before { + content: "\f1ce"; +} +.fa-ra:before, +.fa-resistance:before, +.fa-rebel:before { + content: "\f1d0"; +} +.fa-ge:before, +.fa-empire:before { + content: "\f1d1"; +} +.fa-git-square:before { + content: "\f1d2"; +} +.fa-git:before { + content: "\f1d3"; +} +.fa-y-combinator-square:before, +.fa-yc-square:before, +.fa-hacker-news:before { + content: "\f1d4"; +} +.fa-tencent-weibo:before { + content: "\f1d5"; +} +.fa-qq:before { + content: "\f1d6"; +} +.fa-wechat:before, +.fa-weixin:before { + content: "\f1d7"; +} +.fa-send:before, +.fa-paper-plane:before { + content: "\f1d8"; +} +.fa-send-o:before, +.fa-paper-plane-o:before { + content: "\f1d9"; +} +.fa-history:before { + content: "\f1da"; +} +.fa-circle-thin:before { + content: "\f1db"; +} +.fa-header:before { + content: "\f1dc"; +} +.fa-paragraph:before { + content: "\f1dd"; +} +.fa-sliders:before { + content: "\f1de"; +} +.fa-share-alt:before { + content: "\f1e0"; +} +.fa-share-alt-square:before { + content: "\f1e1"; +} +.fa-bomb:before { + content: "\f1e2"; +} +.fa-soccer-ball-o:before, +.fa-futbol-o:before { + content: "\f1e3"; +} +.fa-tty:before { + content: "\f1e4"; +} +.fa-binoculars:before { + content: "\f1e5"; +} +.fa-plug:before { + content: "\f1e6"; +} +.fa-slideshare:before { + content: "\f1e7"; +} +.fa-twitch:before { + content: "\f1e8"; +} +.fa-yelp:before { + content: "\f1e9"; +} +.fa-newspaper-o:before { + content: "\f1ea"; +} +.fa-wifi:before { + content: "\f1eb"; +} +.fa-calculator:before { + content: "\f1ec"; +} +.fa-paypal:before { + content: "\f1ed"; +} +.fa-google-wallet:before { + content: "\f1ee"; +} +.fa-cc-visa:before { + content: "\f1f0"; +} +.fa-cc-mastercard:before { + content: "\f1f1"; +} +.fa-cc-discover:before { + content: "\f1f2"; +} +.fa-cc-amex:before { + content: "\f1f3"; +} +.fa-cc-paypal:before { + content: "\f1f4"; +} +.fa-cc-stripe:before { + content: "\f1f5"; +} +.fa-bell-slash:before { + content: "\f1f6"; +} +.fa-bell-slash-o:before { + content: "\f1f7"; +} +.fa-trash:before { + content: "\f1f8"; +} +.fa-copyright:before { + content: "\f1f9"; +} +.fa-at:before { + content: "\f1fa"; +} +.fa-eyedropper:before { + content: "\f1fb"; +} +.fa-paint-brush:before { + content: "\f1fc"; +} +.fa-birthday-cake:before { + content: "\f1fd"; +} +.fa-area-chart:before { + content: "\f1fe"; +} +.fa-pie-chart:before { + content: "\f200"; +} +.fa-line-chart:before { + content: "\f201"; +} +.fa-lastfm:before { + content: "\f202"; +} +.fa-lastfm-square:before { + content: "\f203"; +} +.fa-toggle-off:before { + content: "\f204"; +} +.fa-toggle-on:before { + content: "\f205"; +} +.fa-bicycle:before { + content: "\f206"; +} +.fa-bus:before { + content: "\f207"; +} +.fa-ioxhost:before { + content: "\f208"; +} +.fa-angellist:before { + content: "\f209"; +} +.fa-cc:before { + content: "\f20a"; +} +.fa-shekel:before, +.fa-sheqel:before, +.fa-ils:before { + content: "\f20b"; +} +.fa-meanpath:before { + content: "\f20c"; +} +.fa-buysellads:before { + content: "\f20d"; +} +.fa-connectdevelop:before { + content: "\f20e"; +} +.fa-dashcube:before { + content: "\f210"; +} +.fa-forumbee:before { + content: "\f211"; +} +.fa-leanpub:before { + content: "\f212"; +} +.fa-sellsy:before { + content: "\f213"; +} +.fa-shirtsinbulk:before { + content: "\f214"; +} +.fa-simplybuilt:before { + content: "\f215"; +} +.fa-skyatlas:before { + content: "\f216"; +} +.fa-cart-plus:before { + content: "\f217"; +} +.fa-cart-arrow-down:before { + content: "\f218"; +} +.fa-diamond:before { + content: "\f219"; +} +.fa-ship:before { + content: "\f21a"; +} +.fa-user-secret:before { + content: "\f21b"; +} +.fa-motorcycle:before { + content: "\f21c"; +} +.fa-street-view:before { + content: "\f21d"; +} +.fa-heartbeat:before { + content: "\f21e"; +} +.fa-venus:before { + content: "\f221"; +} +.fa-mars:before { + content: "\f222"; +} +.fa-mercury:before { + content: "\f223"; +} +.fa-intersex:before, +.fa-transgender:before { + content: "\f224"; +} +.fa-transgender-alt:before { + content: "\f225"; +} +.fa-venus-double:before { + content: "\f226"; +} +.fa-mars-double:before { + content: "\f227"; +} +.fa-venus-mars:before { + content: "\f228"; +} +.fa-mars-stroke:before { + content: "\f229"; +} +.fa-mars-stroke-v:before { + content: "\f22a"; +} +.fa-mars-stroke-h:before { + content: "\f22b"; +} +.fa-neuter:before { + content: "\f22c"; +} +.fa-genderless:before { + content: "\f22d"; +} +.fa-facebook-official:before { + content: "\f230"; +} +.fa-pinterest-p:before { + content: "\f231"; +} +.fa-whatsapp:before { + content: "\f232"; +} +.fa-server:before { + content: "\f233"; +} +.fa-user-plus:before { + content: "\f234"; +} +.fa-user-times:before { + content: "\f235"; +} +.fa-hotel:before, +.fa-bed:before { + content: "\f236"; +} +.fa-viacoin:before { + content: "\f237"; +} +.fa-train:before { + content: "\f238"; +} +.fa-subway:before { + content: "\f239"; +} +.fa-medium:before { + content: "\f23a"; +} +.fa-yc:before, +.fa-y-combinator:before { + content: "\f23b"; +} +.fa-optin-monster:before { + content: "\f23c"; +} +.fa-opencart:before { + content: "\f23d"; +} +.fa-expeditedssl:before { + content: "\f23e"; +} +.fa-battery-4:before, +.fa-battery:before, +.fa-battery-full:before { + content: "\f240"; +} +.fa-battery-3:before, +.fa-battery-three-quarters:before { + content: "\f241"; +} +.fa-battery-2:before, +.fa-battery-half:before { + content: "\f242"; +} +.fa-battery-1:before, +.fa-battery-quarter:before { + content: "\f243"; +} +.fa-battery-0:before, +.fa-battery-empty:before { + content: "\f244"; +} +.fa-mouse-pointer:before { + content: "\f245"; +} +.fa-i-cursor:before { + content: "\f246"; +} +.fa-object-group:before { + content: "\f247"; +} +.fa-object-ungroup:before { + content: "\f248"; +} +.fa-sticky-note:before { + content: "\f249"; +} +.fa-sticky-note-o:before { + content: "\f24a"; +} +.fa-cc-jcb:before { + content: "\f24b"; +} +.fa-cc-diners-club:before { + content: "\f24c"; +} +.fa-clone:before { + content: "\f24d"; +} +.fa-balance-scale:before { + content: "\f24e"; +} +.fa-hourglass-o:before { + content: "\f250"; +} +.fa-hourglass-1:before, +.fa-hourglass-start:before { + content: "\f251"; +} +.fa-hourglass-2:before, +.fa-hourglass-half:before { + content: "\f252"; +} +.fa-hourglass-3:before, +.fa-hourglass-end:before { + content: "\f253"; +} +.fa-hourglass:before { + content: "\f254"; +} +.fa-hand-grab-o:before, +.fa-hand-rock-o:before { + content: "\f255"; +} +.fa-hand-stop-o:before, +.fa-hand-paper-o:before { + content: "\f256"; +} +.fa-hand-scissors-o:before { + content: "\f257"; +} +.fa-hand-lizard-o:before { + content: "\f258"; +} +.fa-hand-spock-o:before { + content: "\f259"; +} +.fa-hand-pointer-o:before { + content: "\f25a"; +} +.fa-hand-peace-o:before { + content: "\f25b"; +} +.fa-trademark:before { + content: "\f25c"; +} +.fa-registered:before { + content: "\f25d"; +} +.fa-creative-commons:before { + content: "\f25e"; +} +.fa-gg:before { + content: "\f260"; +} +.fa-gg-circle:before { + content: "\f261"; +} +.fa-tripadvisor:before { + content: "\f262"; +} +.fa-odnoklassniki:before { + content: "\f263"; +} +.fa-odnoklassniki-square:before { + content: "\f264"; +} +.fa-get-pocket:before { + content: "\f265"; +} +.fa-wikipedia-w:before { + content: "\f266"; +} +.fa-safari:before { + content: "\f267"; +} +.fa-chrome:before { + content: "\f268"; +} +.fa-firefox:before { + content: "\f269"; +} +.fa-opera:before { + content: "\f26a"; +} +.fa-internet-explorer:before { + content: "\f26b"; +} +.fa-tv:before, +.fa-television:before { + content: "\f26c"; +} +.fa-contao:before { + content: "\f26d"; +} +.fa-500px:before { + content: "\f26e"; +} +.fa-amazon:before { + content: "\f270"; +} +.fa-calendar-plus-o:before { + content: "\f271"; +} +.fa-calendar-minus-o:before { + content: "\f272"; +} +.fa-calendar-times-o:before { + content: "\f273"; +} +.fa-calendar-check-o:before { + content: "\f274"; +} +.fa-industry:before { + content: "\f275"; +} +.fa-map-pin:before { + content: "\f276"; +} +.fa-map-signs:before { + content: "\f277"; +} +.fa-map-o:before { + content: "\f278"; +} +.fa-map:before { + content: "\f279"; +} +.fa-commenting:before { + content: "\f27a"; +} +.fa-commenting-o:before { + content: "\f27b"; +} +.fa-houzz:before { + content: "\f27c"; +} +.fa-vimeo:before { + content: "\f27d"; +} +.fa-black-tie:before { + content: "\f27e"; +} +.fa-fonticons:before { + content: "\f280"; +} +.fa-reddit-alien:before { + content: "\f281"; +} +.fa-edge:before { + content: "\f282"; +} +.fa-credit-card-alt:before { + content: "\f283"; +} +.fa-codiepie:before { + content: "\f284"; +} +.fa-modx:before { + content: "\f285"; +} +.fa-fort-awesome:before { + content: "\f286"; +} +.fa-usb:before { + content: "\f287"; +} +.fa-product-hunt:before { + content: "\f288"; +} +.fa-mixcloud:before { + content: "\f289"; +} +.fa-scribd:before { + content: "\f28a"; +} +.fa-pause-circle:before { + content: "\f28b"; +} +.fa-pause-circle-o:before { + content: "\f28c"; +} +.fa-stop-circle:before { + content: "\f28d"; +} +.fa-stop-circle-o:before { + content: "\f28e"; +} +.fa-shopping-bag:before { + content: "\f290"; +} +.fa-shopping-basket:before { + content: "\f291"; +} +.fa-hashtag:before { + content: "\f292"; +} +.fa-bluetooth:before { + content: "\f293"; +} +.fa-bluetooth-b:before { + content: "\f294"; +} +.fa-percent:before { + content: "\f295"; +} +.fa-gitlab:before { + content: "\f296"; +} +.fa-wpbeginner:before { + content: "\f297"; +} +.fa-wpforms:before { + content: "\f298"; +} +.fa-envira:before { + content: "\f299"; +} +.fa-universal-access:before { + content: "\f29a"; +} +.fa-wheelchair-alt:before { + content: "\f29b"; +} +.fa-question-circle-o:before { + content: "\f29c"; +} +.fa-blind:before { + content: "\f29d"; +} +.fa-audio-description:before { + content: "\f29e"; +} +.fa-volume-control-phone:before { + content: "\f2a0"; +} +.fa-braille:before { + content: "\f2a1"; +} +.fa-assistive-listening-systems:before { + content: "\f2a2"; +} +.fa-asl-interpreting:before, +.fa-american-sign-language-interpreting:before { + content: "\f2a3"; +} +.fa-deafness:before, +.fa-hard-of-hearing:before, +.fa-deaf:before { + content: "\f2a4"; +} +.fa-glide:before { + content: "\f2a5"; +} +.fa-glide-g:before { + content: "\f2a6"; +} +.fa-signing:before, +.fa-sign-language:before { + content: "\f2a7"; +} +.fa-low-vision:before { + content: "\f2a8"; +} +.fa-viadeo:before { + content: "\f2a9"; +} +.fa-viadeo-square:before { + content: "\f2aa"; +} +.fa-snapchat:before { + content: "\f2ab"; +} +.fa-snapchat-ghost:before { + content: "\f2ac"; +} +.fa-snapchat-square:before { + content: "\f2ad"; +} +.fa-pied-piper:before { + content: "\f2ae"; +} +.fa-first-order:before { + content: "\f2b0"; +} +.fa-yoast:before { + content: "\f2b1"; +} +.fa-themeisle:before { + content: "\f2b2"; +} +.fa-google-plus-circle:before, +.fa-google-plus-official:before { + content: "\f2b3"; +} +.fa-fa:before, +.fa-font-awesome:before { + content: "\f2b4"; +} +.fa-handshake-o:before { + content: "\f2b5"; +} +.fa-envelope-open:before { + content: "\f2b6"; +} +.fa-envelope-open-o:before { + content: "\f2b7"; +} +.fa-linode:before { + content: "\f2b8"; +} +.fa-address-book:before { + content: "\f2b9"; +} +.fa-address-book-o:before { + content: "\f2ba"; +} +.fa-vcard:before, +.fa-address-card:before { + content: "\f2bb"; +} +.fa-vcard-o:before, +.fa-address-card-o:before { + content: "\f2bc"; +} +.fa-user-circle:before { + content: "\f2bd"; +} +.fa-user-circle-o:before { + content: "\f2be"; +} +.fa-user-o:before { + content: "\f2c0"; +} +.fa-id-badge:before { + content: "\f2c1"; +} +.fa-drivers-license:before, +.fa-id-card:before { + content: "\f2c2"; +} +.fa-drivers-license-o:before, +.fa-id-card-o:before { + content: "\f2c3"; +} +.fa-quora:before { + content: "\f2c4"; +} +.fa-free-code-camp:before { + content: "\f2c5"; +} +.fa-telegram:before { + content: "\f2c6"; +} +.fa-thermometer-4:before, +.fa-thermometer:before, +.fa-thermometer-full:before { + content: "\f2c7"; +} +.fa-thermometer-3:before, +.fa-thermometer-three-quarters:before { + content: "\f2c8"; +} +.fa-thermometer-2:before, +.fa-thermometer-half:before { + content: "\f2c9"; +} +.fa-thermometer-1:before, +.fa-thermometer-quarter:before { + content: "\f2ca"; +} +.fa-thermometer-0:before, +.fa-thermometer-empty:before { + content: "\f2cb"; +} +.fa-shower:before { + content: "\f2cc"; +} +.fa-bathtub:before, +.fa-s15:before, +.fa-bath:before { + content: "\f2cd"; +} +.fa-podcast:before { + content: "\f2ce"; +} +.fa-window-maximize:before { + content: "\f2d0"; +} +.fa-window-minimize:before { + content: "\f2d1"; +} +.fa-window-restore:before { + content: "\f2d2"; +} +.fa-times-rectangle:before, +.fa-window-close:before { + content: "\f2d3"; +} +.fa-times-rectangle-o:before, +.fa-window-close-o:before { + content: "\f2d4"; +} +.fa-bandcamp:before { + content: "\f2d5"; +} +.fa-grav:before { + content: "\f2d6"; +} +.fa-etsy:before { + content: "\f2d7"; +} +.fa-imdb:before { + content: "\f2d8"; +} +.fa-ravelry:before { + content: "\f2d9"; +} +.fa-eercast:before { + content: "\f2da"; +} +.fa-microchip:before { + content: "\f2db"; +} +.fa-snowflake-o:before { + content: "\f2dc"; +} +.fa-superpowers:before { + content: "\f2dd"; +} +.fa-wpexplorer:before { + content: "\f2de"; +} +.fa-meetup:before { + content: "\f2e0"; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} diff --git a/fedcode/static/css/font-awesome.css.ABOUT b/fedcode/static/css/font-awesome.css.ABOUT new file mode 100644 index 0000000..7f1afbc --- /dev/null +++ b/fedcode/static/css/font-awesome.css.ABOUT @@ -0,0 +1,12 @@ +about_resource: font-awesome.css +version: 4.7.0 +download_url: https://raw.githubusercontent.com/FortAwesome/Font-Awesome/v4.7.0/css/font-awesome.css + +name: font-awesome.css +homepage_url: https://github.com/FortAwesome/Font-Awesome +owner: FortAwesome +author: Dave Gandy +notes: This is the minified version of Font Awesome. + +license: mit +license_file: font-awesome.css.LICENSE \ No newline at end of file diff --git a/fedcode/static/css/font-awesome.css.LICENSE b/fedcode/static/css/font-awesome.css.LICENSE new file mode 100644 index 0000000..fc0b989 --- /dev/null +++ b/fedcode/static/css/font-awesome.css.LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/fedcode/static/fonts/FontAwesome.otf b/fedcode/static/fonts/FontAwesome.otf new file mode 100644 index 0000000..401ec0f Binary files /dev/null and b/fedcode/static/fonts/FontAwesome.otf differ diff --git a/fedcode/static/fonts/FontAwesome.otf.ABOUT b/fedcode/static/fonts/FontAwesome.otf.ABOUT new file mode 100644 index 0000000..8bc27c1 --- /dev/null +++ b/fedcode/static/fonts/FontAwesome.otf.ABOUT @@ -0,0 +1,12 @@ +about_resource: FontAwesome.otf +version: 4.7.0 +download_url: https://github.com/FortAwesome/Font-Awesome/blob/v4.7.0/fonts/FontAwesome.otf?raw=true + +name: FontAwesome.otf +homepage_url: https://github.com/FortAwesome/Font-Awesome +owner: FortAwesome +author: Dave Gandy +notes: Fonts provided by Font Awesome. + +license: ofl-1.1 +license_file: fontawesome.LICENSE \ No newline at end of file diff --git a/fedcode/static/fonts/fontawesome-webfont.eot b/fedcode/static/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/fedcode/static/fonts/fontawesome-webfont.eot differ diff --git a/fedcode/static/fonts/fontawesome-webfont.eot.ABOUT b/fedcode/static/fonts/fontawesome-webfont.eot.ABOUT new file mode 100644 index 0000000..40ba301 --- /dev/null +++ b/fedcode/static/fonts/fontawesome-webfont.eot.ABOUT @@ -0,0 +1,12 @@ +about_resource: fontawesome-webfont.eot +version: 4.7.0 +download_url: https://github.com/FortAwesome/Font-Awesome/blob/v4.7.0/fonts/fontawesome-webfont.eot?raw=true + +name: fontawesome-webfont.eot +homepage_url: https://github.com/FortAwesome/Font-Awesome +owner: FortAwesome +author: Dave Gandy +notes: Fonts provided by Font Awesome. + +license: ofl-1.1 +license_file: fontawesome.LICENSE \ No newline at end of file diff --git a/fedcode/static/fonts/fontawesome-webfont.svg b/fedcode/static/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/fedcode/static/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fedcode/static/fonts/fontawesome-webfont.svg.ABOUT b/fedcode/static/fonts/fontawesome-webfont.svg.ABOUT new file mode 100644 index 0000000..47f9708 --- /dev/null +++ b/fedcode/static/fonts/fontawesome-webfont.svg.ABOUT @@ -0,0 +1,12 @@ +about_resource: fontawesome-webfont.svg +version: 4.7.0 +download_url: https://github.com/FortAwesome/Font-Awesome/blob/v4.7.0/fonts/fontawesome-webfont.svg?raw=true + +name: fontawesome-webfont.svg +homepage_url: https://github.com/FortAwesome/Font-Awesome +owner: FortAwesome +author: Dave Gandy +notes: Fonts provided by Font Awesome. + +license: ofl-1.1 +license_file: fontawesome.LICENSE \ No newline at end of file diff --git a/fedcode/static/fonts/fontawesome-webfont.ttf b/fedcode/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/fedcode/static/fonts/fontawesome-webfont.ttf differ diff --git a/fedcode/static/fonts/fontawesome-webfont.ttf.ABOUT b/fedcode/static/fonts/fontawesome-webfont.ttf.ABOUT new file mode 100644 index 0000000..d2410e1 --- /dev/null +++ b/fedcode/static/fonts/fontawesome-webfont.ttf.ABOUT @@ -0,0 +1,12 @@ +about_resource: fontawesome-webfont.ttf +version: 4.7.0 +download_url: https://github.com/FortAwesome/Font-Awesome/blob/v4.7.0/fonts/fontawesome-webfont.ttf?raw=true + +name: fontawesome-webfont.ttf +homepage_url: https://github.com/FortAwesome/Font-Awesome +owner: FortAwesome +author: Dave Gandy +notes: Fonts provided by Font Awesome. + +license: ofl-1.1 +license_file: fontawesome.LICENSE \ No newline at end of file diff --git a/fedcode/static/fonts/fontawesome-webfont.woff b/fedcode/static/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/fedcode/static/fonts/fontawesome-webfont.woff differ diff --git a/fedcode/static/fonts/fontawesome-webfont.woff.ABOUT b/fedcode/static/fonts/fontawesome-webfont.woff.ABOUT new file mode 100644 index 0000000..4e33d80 --- /dev/null +++ b/fedcode/static/fonts/fontawesome-webfont.woff.ABOUT @@ -0,0 +1,12 @@ +about_resource: fontawesome-webfont.woff +version: 4.7.0 +download_url: https://github.com/FortAwesome/Font-Awesome/blob/v4.7.0/fonts/fontawesome-webfont.woff?raw=true + +name: fontawesome-webfont.woff +homepage_url: https://github.com/FortAwesome/Font-Awesome +owner: FortAwesome +author: Dave Gandy +notes: Fonts provided by Font Awesome. + +license: ofl-1.1 +license_file: fontawesome.LICENSE \ No newline at end of file diff --git a/fedcode/static/fonts/fontawesome-webfont.woff2 b/fedcode/static/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/fedcode/static/fonts/fontawesome-webfont.woff2 differ diff --git a/fedcode/static/fonts/fontawesome-webfont.woff2.ABOUT b/fedcode/static/fonts/fontawesome-webfont.woff2.ABOUT new file mode 100644 index 0000000..e1e3173 --- /dev/null +++ b/fedcode/static/fonts/fontawesome-webfont.woff2.ABOUT @@ -0,0 +1,12 @@ +about_resource: fontawesome-webfont.woff2 +version: 4.7.0 +download_url:https://github.com/FortAwesome/Font-Awesome/blob/v4.7.0/fonts/fontawesome-webfont.woff2?raw=true + +name: fontawesome-webfont.woff2 +homepage_url: https://github.com/FortAwesome/Font-Awesome +owner: FortAwesome +author: Dave Gandy +notes: Fonts provided by Font Awesome. + +license: ofl-1.1 +license_file: fontawesome.LICENSE \ No newline at end of file diff --git a/fedcode/static/fonts/fontawesome.LICENSE b/fedcode/static/fonts/fontawesome.LICENSE new file mode 100644 index 0000000..219d68a --- /dev/null +++ b/fedcode/static/fonts/fontawesome.LICENSE @@ -0,0 +1,97 @@ +Copyright (c) , (), +with Reserved Font Name . +Copyright (c) , (), +with Reserved Font Name . +Copyright (c) , (). + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/fedcode/static/images/favicon-16x16.png b/fedcode/static/images/favicon-16x16.png new file mode 100644 index 0000000..f775715 Binary files /dev/null and b/fedcode/static/images/favicon-16x16.png differ diff --git a/fedcode/static/images/favicon.ico b/fedcode/static/images/favicon.ico new file mode 100644 index 0000000..27cd771 Binary files /dev/null and b/fedcode/static/images/favicon.ico differ diff --git a/fedcode/static/js/jquery-3.7.0.min.js b/fedcode/static/js/jquery-3.7.0.min.js new file mode 100644 index 0000000..e7e29d5 --- /dev/null +++ b/fedcode/static/js/jquery-3.7.0.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.7.0 | (c) OpenJS 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(ie,e){"use strict";var oe=[],r=Object.getPrototypeOf,ae=oe.slice,g=oe.flat?function(e){return oe.flat.call(e)}:function(e){return oe.concat.apply([],e)},s=oe.push,se=oe.indexOf,n={},i=n.toString,ue=n.hasOwnProperty,o=ue.toString,a=o.call(Object),le={},v=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},y=function(e){return null!=e&&e===e.window},C=ie.document,u={type:!0,src:!0,nonce:!0,noModule:!0};function m(e,t,n){var r,i,o=(n=n||C).createElement("script");if(o.text=e,t)for(r in u)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[i.call(e)]||"object":typeof e}var t="3.7.0",l=/HTML$/i,ce=function(e,t){return new ce.fn.init(e,t)};function c(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!v(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+ge+")"+ge+"*"),x=new RegExp(ge+"|>"),j=new RegExp(g),A=new RegExp("^"+t+"$"),D={ID:new RegExp("^#("+t+")"),CLASS:new RegExp("^\\.("+t+")"),TAG:new RegExp("^("+t+"|[*])"),ATTR:new RegExp("^"+p),PSEUDO:new RegExp("^"+g),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+ge+"*(even|odd|(([+-]|)(\\d*)n|)"+ge+"*(?:([+-]|)"+ge+"*(\\d+)|))"+ge+"*\\)|)","i"),bool:new RegExp("^(?:"+f+")$","i"),needsContext:new RegExp("^"+ge+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+ge+"*((?:-\\d)?\\d*)"+ge+"*\\)|)(?=[^-]|$)","i")},N=/^(?:input|select|textarea|button)$/i,q=/^h\d$/i,L=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,H=/[+~]/,O=new RegExp("\\\\[\\da-fA-F]{1,6}"+ge+"?|\\\\([^\\r\\n\\f])","g"),P=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},R=function(){V()},M=J(function(e){return!0===e.disabled&&fe(e,"fieldset")},{dir:"parentNode",next:"legend"});try{k.apply(oe=ae.call(ye.childNodes),ye.childNodes),oe[ye.childNodes.length].nodeType}catch(e){k={apply:function(e,t){me.apply(e,ae.call(t))},call:function(e){me.apply(e,ae.call(arguments,1))}}}function I(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(V(e),e=e||T,C)){if(11!==p&&(u=L.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return k.call(n,a),n}else if(f&&(a=f.getElementById(i))&&I.contains(e,a)&&a.id===i)return k.call(n,a),n}else{if(u[2])return k.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&e.getElementsByClassName)return k.apply(n,e.getElementsByClassName(i)),n}if(!(h[t+" "]||d&&d.test(t))){if(c=t,f=e,1===p&&(x.test(t)||m.test(t))){(f=H.test(t)&&z(e.parentNode)||e)==e&&le.scope||((s=e.getAttribute("id"))?s=ce.escapeSelector(s):e.setAttribute("id",s=S)),o=(l=Y(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+Q(l[o]);c=l.join(",")}try{return k.apply(n,f.querySelectorAll(c)),n}catch(e){h(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return re(t.replace(ve,"$1"),e,n,r)}function W(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function F(e){return e[S]=!0,e}function $(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function B(t){return function(e){return fe(e,"input")&&e.type===t}}function _(t){return function(e){return(fe(e,"input")||fe(e,"button"))&&e.type===t}}function X(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&M(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function U(a){return F(function(o){return o=+o,F(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function z(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}function V(e){var t,n=e?e.ownerDocument||e:ye;return n!=T&&9===n.nodeType&&n.documentElement&&(r=(T=n).documentElement,C=!ce.isXMLDoc(T),i=r.matches||r.webkitMatchesSelector||r.msMatchesSelector,ye!=T&&(t=T.defaultView)&&t.top!==t&&t.addEventListener("unload",R),le.getById=$(function(e){return r.appendChild(e).id=ce.expando,!T.getElementsByName||!T.getElementsByName(ce.expando).length}),le.disconnectedMatch=$(function(e){return i.call(e,"*")}),le.scope=$(function(){return T.querySelectorAll(":scope")}),le.cssHas=$(function(){try{return T.querySelector(":has(*,:jqfake)"),!1}catch(e){return!0}}),le.getById?(b.filter.ID=function(e){var t=e.replace(O,P);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(O,P);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&C){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[]}}),b.find.TAG=function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):t.querySelectorAll(e)},b.find.CLASS=function(e,t){if("undefined"!=typeof t.getElementsByClassName&&C)return t.getElementsByClassName(e)},d=[],$(function(e){var t;r.appendChild(e).innerHTML="",e.querySelectorAll("[selected]").length||d.push("\\["+ge+"*(?:value|"+f+")"),e.querySelectorAll("[id~="+S+"-]").length||d.push("~="),e.querySelectorAll("a#"+S+"+*").length||d.push(".#.+[+~]"),e.querySelectorAll(":checked").length||d.push(":checked"),(t=T.createElement("input")).setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),r.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&d.push(":enabled",":disabled"),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||d.push("\\["+ge+"*name"+ge+"*="+ge+"*(?:''|\"\")")}),le.cssHas||d.push(":has"),d=d.length&&new RegExp(d.join("|")),l=function(e,t){if(e===t)return a=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!le.sortDetached&&t.compareDocumentPosition(e)===n?e===T||e.ownerDocument==ye&&I.contains(ye,e)?-1:t===T||t.ownerDocument==ye&&I.contains(ye,t)?1:o?se.call(o,e)-se.call(o,t):0:4&n?-1:1)}),T}for(e in I.matches=function(e,t){return I(e,null,null,t)},I.matchesSelector=function(e,t){if(V(e),C&&!h[t+" "]&&(!d||!d.test(t)))try{var n=i.call(e,t);if(n||le.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){h(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(O,P),e[3]=(e[3]||e[4]||e[5]||"").replace(O,P),"~="===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]||I.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]&&I.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return D.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&j.test(n)&&(t=Y(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(O,P).toLowerCase();return"*"===e?function(){return!0}:function(e){return fe(e,t)}},CLASS:function(e){var t=s[e+" "];return t||(t=new RegExp("(^|"+ge+")"+e+"("+ge+"|$)"))&&s(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=I.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function T(e,n,r){return v(n)?ce.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?ce.grep(e,function(e){return e===n!==r}):"string"!=typeof n?ce.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(ce.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||k,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:S.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof ce?t[0]:t,ce.merge(this,ce.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:C,!0)),w.test(r[1])&&ce.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=C.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(ce):ce.makeArray(e,this)}).prototype=ce.fn,k=ce(C);var E=/^(?:parents|prev(?:Until|All))/,j={children:!0,contents:!0,next:!0,prev:!0};function A(e,t){while((e=e[t])&&1!==e.nodeType);return e}ce.fn.extend({has:function(e){var t=ce(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,Ce=/^$|^module$|\/(?:java|ecma)script/i;xe=C.createDocumentFragment().appendChild(C.createElement("div")),(be=C.createElement("input")).setAttribute("type","radio"),be.setAttribute("checked","checked"),be.setAttribute("name","t"),xe.appendChild(be),le.checkClone=xe.cloneNode(!0).cloneNode(!0).lastChild.checked,xe.innerHTML="",le.noCloneChecked=!!xe.cloneNode(!0).lastChild.defaultValue,xe.innerHTML="",le.option=!!xe.lastChild;var ke={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function Se(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&fe(e,t)?ce.merge([e],n):n}function Ee(e,t){for(var n=0,r=e.length;n",""]);var je=/<|&#?\w+;/;function Ae(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function Me(e,t){return fe(e,"table")&&fe(11!==t.nodeType?t:t.firstChild,"tr")&&ce(e).children("tbody")[0]||e}function Ie(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function We(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Fe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(_.hasData(e)&&(s=_.get(e).events))for(i in _.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),C.head.appendChild(r[0])},abort:function(){i&&i()}}});var Jt,Kt=[],Zt=/(=)\?(?=&|$)|\?\?/;ce.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Kt.pop()||ce.expando+"_"+jt.guid++;return this[e]=!0,e}}),ce.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Zt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Zt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=v(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Zt,"$1"+r):!1!==e.jsonp&&(e.url+=(At.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||ce.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=ie[r],ie[r]=function(){o=arguments},n.always(function(){void 0===i?ce(ie).removeProp(r):ie[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Kt.push(r)),o&&v(i)&&i(o[0]),o=i=void 0}),"script"}),le.createHTMLDocument=((Jt=C.implementation.createHTMLDocument("").body).innerHTML="
",2===Jt.childNodes.length),ce.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(le.createHTMLDocument?((r=(t=C.implementation.createHTMLDocument("")).createElement("base")).href=C.location.href,t.head.appendChild(r)):t=C),o=!n&&[],(i=w.exec(e))?[t.createElement(i[1])]:(i=Ae([e],t,o),o&&o.length&&ce(o).remove(),ce.merge([],i.childNodes)));var r,i,o},ce.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(ce.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},ce.expr.pseudos.animated=function(t){return ce.grep(ce.timers,function(e){return t===e.elem}).length},ce.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=ce.css(e,"position"),c=ce(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=ce.css(e,"top"),u=ce.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),v(t)&&(t=t.call(e,n,ce.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},ce.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){ce.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===ce.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===ce.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=ce(e).offset()).top+=ce.css(e,"borderTopWidth",!0),i.left+=ce.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-ce.css(r,"marginTop",!0),left:t.left-i.left-ce.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===ce.css(e,"position"))e=e.offsetParent;return e||J})}}),ce.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;ce.fn[t]=function(e){return R(this,function(e,t,n){var r;if(y(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),ce.each(["top","left"],function(e,n){ce.cssHooks[n]=Ye(le.pixelPosition,function(e,t){if(t)return t=Ge(e,n),_e.test(t)?ce(e).position()[n]+"px":t})}),ce.each({Height:"height",Width:"width"},function(a,s){ce.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){ce.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return R(this,function(e,t,n){var r;return y(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?ce.css(e,t,i):ce.style(e,t,n,i)},s,n?e:void 0,n)}})}),ce.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){ce.fn[t]=function(e){return this.on(t,e)}}),ce.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),ce.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){ce.fn[n]=function(e,t){return 0 1 && arguments[1] !== undefined ? arguments[1] : document; + return Array.prototype.slice.call(parent.querySelectorAll(selector), 0); +} + +document.addEventListener('DOMContentLoaded', function () { + setupTabs(); +}); \ No newline at end of file diff --git a/fedcode/static/js/main.js.ABOUT b/fedcode/static/js/main.js.ABOUT new file mode 100644 index 0000000..8e0662a --- /dev/null +++ b/fedcode/static/js/main.js.ABOUT @@ -0,0 +1,15 @@ +about_resource: main.js +purl: pkg:github/jgthms/bulma@0.9.0 +version: v0.9.0 +download_url: https://github.com/jgthms/bulma/archive/refs/tags/0.9.0.tar.gz + +name: bulma css +homepage_url: https://github.com/jgthms/bulma +owner: Jeremy Thomas +author: Jeremy Thomas +notes: This is a generated subset of Bulma JS framework. + +license: mit +license_file: main.js.LICENSE + +copyright: Code copyright 2020 Jeremy Thomas. Code released under the MIT license. \ No newline at end of file diff --git a/fedcode/static/js/main.js.LICENSE b/fedcode/static/js/main.js.LICENSE new file mode 100644 index 0000000..04ab9e0 --- /dev/null +++ b/fedcode/static/js/main.js.LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Jeremy Thomas + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/fedcode/static/js/vote.js b/fedcode/static/js/vote.js new file mode 100644 index 0000000..e47bfe3 --- /dev/null +++ b/fedcode/static/js/vote.js @@ -0,0 +1,67 @@ +function getCookie(name) { + let cookieValue = null; + if (document.cookie && document.cookie !== "") { + const cookies = document.cookie.split(";"); + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i].trim(); + if (cookie.substring(0, name.length + 1) === (name + "=")) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} +function sendVote(url, submit_button, current_value) { + $.ajax({ + type: "PUT", + url: url, + headers: { + "X-Requested-With": "XMLHttpRequest", + "X-CSRFToken": getCookie("csrftoken"), + }, + data: JSON.stringify({"vote-type": submit_button.attr("name")}), + dataType: "json", + success: (data) => { + let obj_id = submit_button.attr("value") + let vote_value = document.getElementsByName(obj_id)[0] + let current_value = vote_value.innerHTML + if (data['vote-type'] === "vote-up"){ + vote_value.innerHTML = parseInt(parseFloat(current_value)) + 1; + } + + if (data['vote-type'] === "vote-down") { + vote_value.innerHTML = parseInt(parseFloat(current_value)) - 1; + } + }, + error: (error) => { + console.log(error); + } + }); +} +$(document).ready(function () { + $("form[name='vote-notes']").submit(function (event) { + event.preventDefault(); + let submit_button = $(event.originalEvent.submitter); + if ((submit_button.attr("name") === "vote-up") || + (submit_button.attr("name") === "vote-down")) { + let note_id = submit_button.attr("value") + let url = "/notes/"+ note_id +"/votes/" + let current_value = $( "#" + note_id).text(); + sendVote(url, submit_button, current_value); + } + }); + + $("form[name='vote-review']").submit(function (event) { + event.preventDefault(); + let submit_button = $(event.originalEvent.submitter); + if ((submit_button.attr("name") === "vote-up") || + (submit_button.attr("name") === "vote-down")) { + let review_id = submit_button.attr("value") + let url = "/reviews/"+ review_id + "/votes/" + let current_value = $("#votes-review-value").text(); + sendVote(url, submit_button , current_value); + } + }); + +}); \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages.ABOUT b/fedcode/static/pictogram-gh-pages.ABOUT new file mode 100644 index 0000000..613c468 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages.ABOUT @@ -0,0 +1,8 @@ +about_resource: pictogram-gh-pages +download_url: https://github.com/librariesio/pictogram/archive/cf3cdf43ab9024258a56ae74afbb7a49517d56f4.zip + +name: pictogram-gh-pages +license: mit +license_file: pictogram-gh-pages.LICENSE + +copyright: Code copyright 2020 Jeremy Thomas. Code released under the MIT license. diff --git a/fedcode/static/pictogram-gh-pages.LICENSE b/fedcode/static/pictogram-gh-pages.LICENSE new file mode 100644 index 0000000..45d4c09 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages.LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2016 Oli Evans + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/actionscript/actionscript.json b/fedcode/static/pictogram-gh-pages/actionscript/actionscript.json new file mode 100644 index 0000000..e2425e2 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/actionscript/actionscript.json @@ -0,0 +1,21 @@ +{ + "name": "actionscript", + "source": { + "url": "http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/authors/large/a/actionscript_lg.jpg.adimg.mw.138.png", + "referrer": "http://www.adobe.com/devnet/actionscript.html", + "headers": { + "server": "Apache", + "last-modified": "Tue, 17 Mar 2015 23:12:24 GMT", + "etag": "\"17fb36fd9-1191-5118419803ca3\"", + "accept-ranges": "bytes", + "content-length": "4497", + "cache-control": "max-age=900, s-maxage=300", + "content-type": "image/png", + "date": "Sat, 21 Mar 2015 20:16:47 GMT", + "x-cache": "MISS from cache_server", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/actionscript/actionscript.orig.png b/fedcode/static/pictogram-gh-pages/actionscript/actionscript.orig.png new file mode 100644 index 0000000..6a1e280 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/actionscript/actionscript.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/actionscript/actionscript.png b/fedcode/static/pictogram-gh-pages/actionscript/actionscript.png new file mode 100644 index 0000000..20b3c43 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/actionscript/actionscript.png differ diff --git a/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.json b/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.json new file mode 100644 index 0000000..bb141aa --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.json @@ -0,0 +1,22 @@ +{ + "name": "alcatraz", + "source": { + "url": "http://alcatraz.io/images/logo.svg", + "referrer": "http://alcatraz.io/", + "headers": { + "server": "GitHub.com", + "date": "Sat, 21 Mar 2015 09:58:21 GMT", + "content-type": "image/svg+xml", + "content-length": "2834", + "last-modified": "Wed, 11 Mar 2015 19:16:07 GMT", + "expires": "Sat, 21 Mar 2015 10:08:21 GMT", + "cache-control": "max-age=600", + "access-control-allow-origin": "*", + "accept-ranges": "bytes", + "x-cache": "MISS from cache_server", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.png b/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.png new file mode 100644 index 0000000..8d317f2 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.png differ diff --git a/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.svg b/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.svg new file mode 100644 index 0000000..a0679ce --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/alcatraz/alcatraz.svg @@ -0,0 +1,24 @@ + + + logo + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/alpine/alogo.svg b/fedcode/static/pictogram-gh-pages/alpine/alogo.svg new file mode 100644 index 0000000..cafc775 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/alpine/alogo.svg @@ -0,0 +1,3 @@ + + +image/svg+xml \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/alpine/alpine.png b/fedcode/static/pictogram-gh-pages/alpine/alpine.png new file mode 100644 index 0000000..976f428 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/alpine/alpine.png differ diff --git a/fedcode/static/pictogram-gh-pages/alpine/alpine.svg.ABOUT b/fedcode/static/pictogram-gh-pages/alpine/alpine.svg.ABOUT new file mode 100644 index 0000000..afa5436 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/alpine/alpine.svg.ABOUT @@ -0,0 +1,3 @@ +about_resource: alpine.png +download_url: https://wiki.alpinelinux.org/images/alogo.svg +notes: converted svg image ( alogo.svg ) to png ( alpine.png ) using gimp \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/apache/apache.gif b/fedcode/static/pictogram-gh-pages/apache/apache.gif new file mode 100644 index 0000000..94f1892 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/apache/apache.gif differ diff --git a/fedcode/static/pictogram-gh-pages/apache/apache.json b/fedcode/static/pictogram-gh-pages/apache/apache.json new file mode 100644 index 0000000..04b47d6 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/apache/apache.json @@ -0,0 +1,18 @@ +{ + "name": "apacheconf", + "source": { + "url": "https://accumulo.apache.org/images/feather-small.gif", + "referrer": "https://accumulo.apache.org", + "headers": { + "date": "Fri, 20 Mar 2015 22:40:14 GMT", + "server": "Apache/2.4.12 (Unix) OpenSSL/1.0.1l", + "last-modified": "Sun, 01 Apr 2012 01:27:29 GMT", + "etag": "\"1d4c-4bc93fa2003e8\"", + "accept-ranges": "bytes", + "content-length": "7500", + "keep-alive": "timeout=5, max=100", + "connection": "Keep-Alive", + "content-type": "image/gif" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/apache/apache.png b/fedcode/static/pictogram-gh-pages/apache/apache.png new file mode 100644 index 0000000..21ec4f7 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/apache/apache.png differ diff --git a/fedcode/static/pictogram-gh-pages/assembly/assembly.json b/fedcode/static/pictogram-gh-pages/assembly/assembly.json new file mode 100644 index 0000000..727c3ee --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/assembly/assembly.json @@ -0,0 +1,27 @@ +{ + "name": "assembly", + "source": { + "url": "http://i.imgur.com/c18lFaQ.png", + "referrer": "http://imgur.com/gallery/72ouk", + "headers": { + "last-modified": "Sat, 17 Jan 2015 11:08:15 GMT", + "etag": "\"6415d32fde1d3dadb654a4fc023c8b5f\"", + "content-type": "image/png", + "cache-control": "public, max-age=31536000", + "content-length": "18343", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 20:46:36 GMT", + "x-served-by": "cache-iad2127-IAD, cache-lhr6322-LHR", + "x-cache": "HIT, HIT, HIT from cache_server", + "x-cache-hits": "1, 1", + "x-timer": "S1426970796.664084,VS0,VE0", + "access-control-allow-methods": "GET, OPTIONS", + "access-control-allow-origin": "*", + "server": "cat factory 1.0", + "age": "2705717", + "x-cache-lookup": "HIT from cache_server:3128", + "via": "1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/assembly/assembly.orig.png b/fedcode/static/pictogram-gh-pages/assembly/assembly.orig.png new file mode 100644 index 0000000..fb35b05 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/assembly/assembly.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/assembly/assembly.png b/fedcode/static/pictogram-gh-pages/assembly/assembly.png new file mode 100644 index 0000000..67c1187 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/assembly/assembly.png differ diff --git a/fedcode/static/pictogram-gh-pages/atom/atom.json b/fedcode/static/pictogram-gh-pages/atom/atom.json new file mode 100644 index 0000000..06855bc --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/atom/atom.json @@ -0,0 +1,32 @@ +{ + "name": "atom", + "source": { + "url": "https://avatars0.githubusercontent.com/u/1089146?v=3&s=200", + "referrer": "https://github.com/atom", + "headers": { + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"4d17a873f85c8704e8464279e7a57c6267fd7176\"", + "last-modified": "Tue, 06 May 2014 14:29:46 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "cda92f04-0148-11e5-89db-f7ea2b8b01eb", + "x-xss-protection": "1; mode=block", + "content-length": "10458", + "accept-ranges": "bytes", + "date": "Sat, 23 May 2015 18:15:21 GMT", + "via": "1.1 varnish", + "connection": "keep-alive", + "x-served-by": "cache-lcy1131-LCY", + "x-cache": "HIT", + "x-cache-hits": "12", + "expires": "Sat, 23 May 2015 18:20:21 GMT", + "source-age": "20131", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/atom/atom.png b/fedcode/static/pictogram-gh-pages/atom/atom.png new file mode 100644 index 0000000..04d074b Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/atom/atom.png differ diff --git a/fedcode/static/pictogram-gh-pages/biicode/biicode.json b/fedcode/static/pictogram-gh-pages/biicode/biicode.json new file mode 100644 index 0000000..f426fac --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/biicode/biicode.json @@ -0,0 +1,31 @@ +{ + "name": "biicode", + "source": { + "url": "https://avatars2.githubusercontent.com/u/4687531?v=3&s=200", + "referrer": "https://github.com/biicode", + "headers": { + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Tue, 05 Nov 2013 10:54:24 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "f578c538-00a7-11e5-862a-21d76f3a5017", + "x-xss-protection": "1; mode=block", + "content-length": "21333", + "accept-ranges": "bytes", + "date": "Fri, 22 May 2015 17:28:28 GMT", + "via": "1.1 varnish", + "connection": "keep-alive", + "x-served-by": "cache-lcy1131-LCY", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Fri, 22 May 2015 17:33:28 GMT", + "source-age": "0", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/biicode/biicode.png b/fedcode/static/pictogram-gh-pages/biicode/biicode.png new file mode 100644 index 0000000..a34a8fc Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/biicode/biicode.png differ diff --git a/fedcode/static/pictogram-gh-pages/bower/bower.json b/fedcode/static/pictogram-gh-pages/bower/bower.json new file mode 100644 index 0000000..81c127c --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/bower/bower.json @@ -0,0 +1,34 @@ +{ + "name": "bower", + "source": { + "url": "https://avatars3.githubusercontent.com/u/3709251?v=3&s=200", + "referrer": "https://github.com/bower", + "headers": { + "date": "Sun, 15 Mar 2015 10:25:48 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Mon, 22 Apr 2013 22:23:58 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "a5b9c5b2-cafd-11e4-8940-a7214a82c2cb", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "21715", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-fra1221-FRA", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sun, 15 Mar 2015 10:30:48 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/bower/bower.png b/fedcode/static/pictogram-gh-pages/bower/bower.png new file mode 100644 index 0000000..555f195 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/bower/bower.png differ diff --git a/fedcode/static/pictogram-gh-pages/c#/c#.json b/fedcode/static/pictogram-gh-pages/c#/c#.json new file mode 100644 index 0000000..642f72f --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/c#/c#.json @@ -0,0 +1,27 @@ +{ + "name": "c#", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/C_Sharp_wordmark.svg/200px-C_Sharp_wordmark.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:C_Sharp_wordmark.svg", + "headers": { + "x-object-meta-sha1base36": "ml2eicl9c1m16cq0odrib38cel1ux6v", + "content-disposition": "inline;filename*=UTF-8''C_Sharp_wordmark.svg.png", + "last-modified": "Sun, 19 Jan 2014 18:16:45 GMT", + "etag": "4d188cbf2629549d7a3bbd8291388e93", + "x-timestamp": "1390155404.18857", + "content-type": "image/png", + "x-trans-id": "txe325d071e61f40ec8c0e0-00550a9ce0", + "x-varnish": "2844179884 2811213489, 2767017012 2621554093, 3191517447", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "2982", + "accept-ranges": "bytes", + "date": "Fri, 20 Mar 2015 13:55:50 GMT", + "age": "100870", + "connection": "keep-alive", + "x-cache": "cp1061 hit (1), cp3010 hit (24), cp3007 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/c#/c#.orig.png b/fedcode/static/pictogram-gh-pages/c#/c#.orig.png new file mode 100644 index 0000000..7959a5f Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/c#/c#.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/c#/c#.png b/fedcode/static/pictogram-gh-pages/c#/c#.png new file mode 100644 index 0000000..fdc8155 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/c#/c#.png differ diff --git a/fedcode/static/pictogram-gh-pages/c++/c++.json b/fedcode/static/pictogram-gh-pages/c++/c++.json new file mode 100644 index 0000000..5293e92 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/c++/c++.json @@ -0,0 +1,28 @@ +{ + "name": "c++", + "source": { + "url": "https://pbs.twimg.com/profile_images/2515409731/rxrc5tqf0r7y98g1sfdj_200x200.png", + "referrer": "https://twitter.com/isocpp", + "headers": { + "date": "Sat, 14 Mar 2015 17:59:25 GMT", + "server": "tsa_b", + "cache-control": "max-age=604800, must-revalidate", + "content-md5": "al1uh3KUX4vfvROaOOZalg==", + "last-modified": "Thu, 04 Nov 2010 01:42:54 GMT", + "x-connection-hash": "04a3eacd26d3126992f7272003c5f60b", + "x-response-time": "17", + "content-type": "image/png", + "content-length": "50921", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "age": "0", + "x-served-by": "mtc-tw-lon2-1-TWLON2", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sun, 29 Mar 2015 17:59:25 GMT", + "x-content-type-options": "nosniff", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/c++/c++.png b/fedcode/static/pictogram-gh-pages/c++/c++.png new file mode 100644 index 0000000..77cadc3 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/c++/c++.png differ diff --git a/fedcode/static/pictogram-gh-pages/c/c.json b/fedcode/static/pictogram-gh-pages/c/c.json new file mode 100644 index 0000000..855222d --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/c/c.json @@ -0,0 +1,27 @@ +{ + "name": "c", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/3/35/The_C_Programming_Language_logo.svg/200px-The_C_Programming_Language_logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:The_C_Programming_Language_logo.svg", + "headers": { + "x-object-meta-sha1base36": "5wzecx02acldqfbbn9z9gsa2s78zjwv", + "content-disposition": "inline;filename*=UTF-8''The_C_Programming_Language_logo.svg.png", + "last-modified": "Sat, 03 May 2014 06:33:17 GMT", + "etag": "a7c96e0cd2cf40302b0cea4731d3ddc1", + "x-timestamp": "1399098796.67508", + "content-type": "image/png", + "x-trans-id": "tx6d193c09670a41a29e5f8-00550b5c66", + "x-varnish": "3288601965 3250119526, 948536444 891627264, 4230760775", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "11871", + "accept-ranges": "bytes", + "date": "Fri, 20 Mar 2015 13:53:39 GMT", + "age": "51709", + "connection": "keep-alive", + "x-cache": "cp1051 hit (3), cp3015 hit (3), cp3015 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/c/c.png b/fedcode/static/pictogram-gh-pages/c/c.png new file mode 100644 index 0000000..1db3900 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/c/c.png differ diff --git a/fedcode/static/pictogram-gh-pages/cargo/cargo.json b/fedcode/static/pictogram-gh-pages/cargo/cargo.json new file mode 100644 index 0000000..8527760 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/cargo/cargo.json @@ -0,0 +1,31 @@ +{ + "name": "cargo", + "source": { + "url": "https://raw.githubusercontent.com/rust-lang/crates.io/master/public/assets/Cargo-Logo-Small.png", + "referrer": "https://github.com/rust-lang/crates.io/blob/master/public/assets/Cargo-Logo-Small.png", + "headers": { + "date": "Mon, 16 Mar 2015 23:45:39 GMT", + "server": "Apache", + "access-control-allow-origin": "https://render.githubusercontent.com", + "content-security-policy": "default-src 'none'", + "x-xss-protection": "1; mode=block", + "x-frame-options": "deny", + "x-content-type-options": "nosniff", + "strict-transport-security": "max-age=31536000", + "etag": "\"9a94dcc871a3bd606cef6f0647924a3447840304\"", + "content-type": "image/png", + "cache-control": "max-age=300", + "content-length": "58730", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6323-LHR", + "x-cache": "MISS", + "x-cache-hits": "0", + "vary": "Authorization,Accept-Encoding", + "expires": "Mon, 16 Mar 2015 23:50:39 GMT", + "source-age": "0", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/cargo/cargo.png b/fedcode/static/pictogram-gh-pages/cargo/cargo.png new file mode 100644 index 0000000..240c212 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/cargo/cargo.png differ diff --git a/fedcode/static/pictogram-gh-pages/carthage/carthage.json b/fedcode/static/pictogram-gh-pages/carthage/carthage.json new file mode 100644 index 0000000..bdb5c88 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/carthage/carthage.json @@ -0,0 +1,33 @@ +{ + "name": "carthage", + "source": { + "url": "https://avatars0.githubusercontent.com/u/9146792?v=3&s=200", + "referrer": "https://github.com/carthage", + "headers": { + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"66e578efa7494ef9ba0ede5f0ae71ecfbb9700ff\"", + "last-modified": "Mon, 01 Dec 2014 19:58:19 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-xss-protection": "1; mode=block", + "x-github-request-id": "B91F131A:3F6A:13554528:56C3B3FE", + "content-length": "124979", + "accept-ranges": "bytes", + "date": "Fri, 26 Feb 2016 19:12:22 GMT", + "via": "1.1 varnish", + "connection": "close", + "x-served-by": "cache-lhr6323-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "access-control-allow-origin": "*", + "x-fastly-request-id": "708eb9bfa0fc544d75a385f6847617ca8f267878", + "expires": "Fri, 26 Feb 2016 19:17:22 GMT", + "source-age": "847767", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/carthage/carthage.png b/fedcode/static/pictogram-gh-pages/carthage/carthage.png new file mode 100644 index 0000000..0dc5b6c Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/carthage/carthage.png differ diff --git a/fedcode/static/pictogram-gh-pages/clojars/clojars.json b/fedcode/static/pictogram-gh-pages/clojars/clojars.json new file mode 100644 index 0000000..a9d0109 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/clojars/clojars.json @@ -0,0 +1,31 @@ +{ + "name": "clojars", + "source": { + "url": "https://raw.githubusercontent.com/ato/clojars-web/master/resources/public/images/clojars-logo-big.png", + "referrer": "https://clojars.org/", + "headers": { + "date": "Wed, 18 Mar 2015 00:13:25 GMT", + "server": "Apache", + "access-control-allow-origin": "https://render.githubusercontent.com", + "content-security-policy": "default-src 'none'", + "x-xss-protection": "1; mode=block", + "x-frame-options": "deny", + "x-content-type-options": "nosniff", + "strict-transport-security": "max-age=31536000", + "etag": "\"1d13e9b92e80e87bc0e6cca6ab2a21cef2acc869\"", + "content-type": "image/png", + "cache-control": "max-age=300", + "content-length": "7274", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6322-LHR", + "x-cache": "MISS", + "x-cache-hits": "0", + "vary": "Authorization,Accept-Encoding", + "expires": "Wed, 18 Mar 2015 00:18:25 GMT", + "source-age": "0", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/clojars/clojars.orig.png b/fedcode/static/pictogram-gh-pages/clojars/clojars.orig.png new file mode 100644 index 0000000..43b3218 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/clojars/clojars.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/clojars/clojars.png b/fedcode/static/pictogram-gh-pages/clojars/clojars.png new file mode 100644 index 0000000..2d163a0 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/clojars/clojars.png differ diff --git a/fedcode/static/pictogram-gh-pages/clojure/clojure.json b/fedcode/static/pictogram-gh-pages/clojure/clojure.json new file mode 100644 index 0000000..5a432b8 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/clojure/clojure.json @@ -0,0 +1,34 @@ +{ + "name": "clojure", + "source": { + "url": "https://avatars2.githubusercontent.com/u/317875?v=3&s=200", + "referrer": "https://github.com/clojure", + "headers": { + "date": "Sat, 14 Mar 2015 16:28:54 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Wed, 30 Jun 2010 18:30:22 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "f0b970e0-ca66-11e4-8a7e-67a35a28dcaf", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "25770", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-ams4136-AMS", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Sat, 14 Mar 2015 16:33:54 GMT", + "source-age": "115", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/clojure/clojure.png b/fedcode/static/pictogram-gh-pages/clojure/clojure.png new file mode 100644 index 0000000..d18e823 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/clojure/clojure.png differ diff --git a/fedcode/static/pictogram-gh-pages/cocoapods/cocoapods.json b/fedcode/static/pictogram-gh-pages/cocoapods/cocoapods.json new file mode 100644 index 0000000..1095ce1 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/cocoapods/cocoapods.json @@ -0,0 +1,35 @@ +{ + "name": "cocoapods", + "source": { + "url": "https://avatars1.githubusercontent.com/u/1189714?v=3&s=200", + "referrer": "https://github.com/cocoapods", + "headers": { + "date": "Wed, 18 Mar 2015 10:22:45 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"8275215b21b57e0561fa8ceb1fd9a4d4793626bc\"", + "last-modified": "Fri, 28 Mar 2014 17:10:48 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "d73de257-c0ef-11e4-80eb-0ba46456c81f", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "8658", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6324-LHR", + "x-cache": "HIT", + "x-cache-hits": "12", + "expires": "Wed, 18 Mar 2015 10:27:45 GMT", + "source-age": "1364458", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/cocoapods/cocoapods.png b/fedcode/static/pictogram-gh-pages/cocoapods/cocoapods.png new file mode 100644 index 0000000..5db6237 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/cocoapods/cocoapods.png differ diff --git a/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.json b/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.json new file mode 100644 index 0000000..4d510bc --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.json @@ -0,0 +1,18 @@ +{ + "name": "coffeescript", + "source": { + "url": "http://coffeescript.org/documentation/images/logo.png", + "referrer": "http://coffeescript.org/", + "headers": { + "server": "GitHub.com", + "date": "Sat, 14 Mar 2015 19:01:28 GMT", + "content-type": "image/png", + "content-length": "12591", + "last-modified": "Wed, 18 Feb 2015 20:48:58 GMT", + "expires": "Sat, 14 Mar 2015 19:11:28 GMT", + "cache-control": "max-age=600", + "access-control-allow-origin": "*", + "accept-ranges": "bytes" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.orig.png b/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.orig.png new file mode 100644 index 0000000..4fd697c Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.png b/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.png new file mode 100644 index 0000000..634c626 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/coffeescript/coffeescript.png differ diff --git a/fedcode/static/pictogram-gh-pages/cpan/cpan.json b/fedcode/static/pictogram-gh-pages/cpan/cpan.json new file mode 100644 index 0000000..9b39741 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/cpan/cpan.json @@ -0,0 +1,27 @@ +{ + "name": "cpan", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/en/1/14/The_logo_of_CPAN.png", + "referrer": "http://en.wikipedia.org/wiki/File:The_logo_of_CPAN.png", + "headers": { + "x-object-meta-sha1base36": "hjx38dzcq6mldoe4oi7n0ml41c1ej6f", + "last-modified": "Fri, 18 Apr 2014 18:32:39 GMT", + "etag": "cad4d0c6684a04cff9e221fa07ba1448", + "x-timestamp": "1397845958.02096", + "content-type": "image/png", + "x-trans-id": "tx5ef1c302903a41f6a5535-00550b1869", + "x-varnish": "2701087188 2682602333, 2182943610 1989768456, 2266467108", + "content-length": "4282", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 10:09:18 GMT", + "age": "142053", + "x-cache": "cp1062 hit (1), cp3003 hit (7), cp3006 frontend miss (0), MISS from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/cpan/cpan.orig.png b/fedcode/static/pictogram-gh-pages/cpan/cpan.orig.png new file mode 100644 index 0000000..af0eacd Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/cpan/cpan.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/cpan/cpan.png b/fedcode/static/pictogram-gh-pages/cpan/cpan.png new file mode 100644 index 0000000..fcb0e1e Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/cpan/cpan.png differ diff --git a/fedcode/static/pictogram-gh-pages/cran/cran.json b/fedcode/static/pictogram-gh-pages/cran/cran.json new file mode 100644 index 0000000..068bd38 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/cran/cran.json @@ -0,0 +1,28 @@ +{ + "name": "cran", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/R_logo.svg/200px-R_logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:R_logo.svg", + "headers": { + "x-object-meta-sha1base36": "4k5u08r0xmrgw9as845n2yxbcfx2ohl", + "content-disposition": "inline;filename*=UTF-8''R_logo.svg.png", + "last-modified": "Wed, 24 Sep 2014 00:32:30 GMT", + "etag": "4d2a3c398e6dfebc8db0049b2d74055b", + "x-timestamp": "1411518749.34215", + "content-type": "image/png", + "x-trans-id": "tx2f2ab271ce2e4e2686449-00550c4ed7", + "x-varnish": "2379257310 2363119544, 2379253562 2317379629, 3417700854", + "content-length": "35295", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 10:07:47 GMT", + "x-cache": "cp1049 hit (121), cp3017 hit (351), cp3004 frontend miss (0), HIT from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "age": "62539", + "x-cache-lookup": "HIT from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/cran/cran.png b/fedcode/static/pictogram-gh-pages/cran/cran.png new file mode 100644 index 0000000..1d4fcd7 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/cran/cran.png differ diff --git a/fedcode/static/pictogram-gh-pages/crystal/crystal.json b/fedcode/static/pictogram-gh-pages/crystal/crystal.json new file mode 100644 index 0000000..2a52818 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/crystal/crystal.json @@ -0,0 +1,33 @@ +{ + "name": "crystal", + "source": { + "url": "https://avatars0.githubusercontent.com/u/6539796?v=3&s=200", + "referrer": "https://github.com/crystal-lang", + "headers": { + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"385531d498d8d3083523aa2eb9510d4160fc3f47\"", + "last-modified": "Fri, 28 Aug 2015 20:04:02 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-xss-protection": "1; mode=block", + "x-github-request-id": "B91F121F:4C0D:8668712:56CDD763", + "content-length": "5510", + "accept-ranges": "bytes", + "date": "Tue, 01 Mar 2016 09:40:49 GMT", + "via": "1.1 varnish", + "connection": "close", + "x-served-by": "cache-lcy1122-LCY", + "x-cache": "HIT", + "x-cache-hits": "1", + "access-control-allow-origin": "*", + "x-fastly-request-id": "cc0dcec264acb2224de22404096688835e70b466", + "expires": "Tue, 01 Mar 2016 09:45:49 GMT", + "source-age": "494653", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/crystal/crystal.png b/fedcode/static/pictogram-gh-pages/crystal/crystal.png new file mode 100644 index 0000000..9d9cc02 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/crystal/crystal.png differ diff --git a/fedcode/static/pictogram-gh-pages/css/css.json b/fedcode/static/pictogram-gh-pages/css/css.json new file mode 100644 index 0000000..702e59a --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/css/css.json @@ -0,0 +1,18 @@ +{ + "name": "css", + "source": { + "url": "http://www.bobbyberberyan.com/wp-content/uploads/2012/03/HTML5CSS3Logos.svg", + "referrer": "http://www.bobbyberberyan.com/2012/03/html-5-css-3-logos/", + "headers": { + "date": "Sat, 14 Mar 2015 18:38:56 GMT", + "server": "Apache", + "last-modified": "Thu, 22 Mar 2012 17:12:34 GMT", + "etag": "\"ddc-4bbd80395e597\"", + "accept-ranges": "bytes", + "content-length": "3548", + "keep-alive": "timeout=5, max=100", + "connection": "Keep-Alive", + "content-type": "image/svg+xml" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/css/css.png b/fedcode/static/pictogram-gh-pages/css/css.png new file mode 100644 index 0000000..70c12d2 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/css/css.png differ diff --git a/fedcode/static/pictogram-gh-pages/css/css.svg b/fedcode/static/pictogram-gh-pages/css/css.svg new file mode 100644 index 0000000..b0db13b --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/css/css.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fedcode/static/pictogram-gh-pages/d/d.json b/fedcode/static/pictogram-gh-pages/d/d.json new file mode 100644 index 0000000..b4f5159 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/d/d.json @@ -0,0 +1,34 @@ +{ + "name": "d", + "source": { + "url": "https://avatars3.githubusercontent.com/u/565913?v=3&s=200", + "referrer": "https://github.com/D-Programming-Language", + "headers": { + "date": "Tue, 17 Mar 2015 21:57:00 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Sat, 15 Jan 2011 08:35:22 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "898ccc4f-ccf0-11e4-82c1-661745da0098", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "24001", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6335-LHR", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Tue, 17 Mar 2015 22:02:00 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/d/d.png b/fedcode/static/pictogram-gh-pages/d/d.png new file mode 100644 index 0000000..9625121 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/d/d.png differ diff --git a/fedcode/static/pictogram-gh-pages/dart/dart.json b/fedcode/static/pictogram-gh-pages/dart/dart.json new file mode 100644 index 0000000..10d0c25 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/dart/dart.json @@ -0,0 +1,35 @@ +{ + "name": "dart", + "source": { + "url": "https://avatars3.githubusercontent.com/u/1609975?v=3&s=200", + "referrer": "https://github.com/dart-lang", + "headers": { + "date": "Mon, 16 Mar 2015 23:11:23 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"5bb0f27e278424f9b2b57d13d5963798eeffde44\"", + "last-modified": "Tue, 29 Apr 2014 15:18:02 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "156c8588-c2a6-11e4-8e0b-5ea87ed5aba0", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "29207", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6334-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Mon, 16 Mar 2015 23:16:23 GMT", + "source-age": "1049552", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/dart/dart.png b/fedcode/static/pictogram-gh-pages/dart/dart.png new file mode 100644 index 0000000..d378fd8 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/dart/dart.png differ diff --git a/fedcode/static/pictogram-gh-pages/dub/dub.json b/fedcode/static/pictogram-gh-pages/dub/dub.json new file mode 100644 index 0000000..229a86b --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/dub/dub.json @@ -0,0 +1,18 @@ +{ + "name": "dub", + "source": { + "url": "http://code.dlang.org/images/logo-small.png", + "referrer": "http://code.dlang.org/", + "headers": { + "server": "vibe.d/0.7.22", + "date": "Tue, 17 Mar 2015 22:01:17 GMT", + "keep-alive": "timeout=10", + "last-modified": "Fri, 07 Dec 2012 16:30:27 GMT", + "etag": "\"09CE4277EF625410C1F51424793E5EC7\"", + "expires": "Wed, 18 Mar 2015 22:01:17 GMT", + "cache-control": "max-age=86400", + "content-type": "image/png", + "content-length": "2255" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/dub/dub.orig.png b/fedcode/static/pictogram-gh-pages/dub/dub.orig.png new file mode 100644 index 0000000..ef97637 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/dub/dub.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/dub/dub.png b/fedcode/static/pictogram-gh-pages/dub/dub.png new file mode 100644 index 0000000..ef97637 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/dub/dub.png differ diff --git a/fedcode/static/pictogram-gh-pages/elixir/elixir.json b/fedcode/static/pictogram-gh-pages/elixir/elixir.json new file mode 100644 index 0000000..4e9eb94 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/elixir/elixir.json @@ -0,0 +1,34 @@ +{ + "name": "elixir", + "source": { + "url": "https://avatars0.githubusercontent.com/u/1481354?v=3&s=200", + "referrer": "https://github.com/elixir-lang", + "headers": { + "date": "Sat, 14 Mar 2015 18:01:45 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Sun, 25 Nov 2012 17:23:59 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "2d71b851-ca74-11e4-80f1-b761e8b8d339", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "23016", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6331-LHR", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sat, 14 Mar 2015 18:06:45 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/elixir/elixir.png b/fedcode/static/pictogram-gh-pages/elixir/elixir.png new file mode 100644 index 0000000..a740c11 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/elixir/elixir.png differ diff --git a/fedcode/static/pictogram-gh-pages/elm/elm.json b/fedcode/static/pictogram-gh-pages/elm/elm.json new file mode 100644 index 0000000..adfd0ec --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/elm/elm.json @@ -0,0 +1,34 @@ +{ + "name": "elm", + "source": { + "url": "https://avatars0.githubusercontent.com/u/4359353?v=3&s=200", + "referrer": "https://github.com/elm-lang", + "headers": { + "date": "Mon, 23 Mar 2015 18:21:10 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Wed, 12 Mar 2014 16:48:22 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "6173b377-d189-11e4-82f4-e6d28114a994", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "17159", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6327-LHR", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Mon, 23 Mar 2015 18:26:10 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/elm/elm.png b/fedcode/static/pictogram-gh-pages/elm/elm.png new file mode 100644 index 0000000..4fc78b6 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/elm/elm.png differ diff --git a/fedcode/static/pictogram-gh-pages/emacs/emacs.json b/fedcode/static/pictogram-gh-pages/emacs/emacs.json new file mode 100644 index 0000000..501df73 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/emacs/emacs.json @@ -0,0 +1,26 @@ +{ + "name": "emacs", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Emacs-logo.svg/200px-Emacs-logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Emacs-logo.svg", + "headers": { + "last-modified": "Sat, 26 Oct 2013 06:45:23 GMT", + "etag": "5342afd2e38bdb7dbb17ae941c7088dd", + "x-timestamp": "1382769922.32171", + "content-type": "image/png", + "x-trans-id": "txf256c09d77574c98b65df-00550ce144", + "x-varnish": "1905484777 1875809950, 1434740035, 2701353227", + "content-length": "21580", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 09:52:06 GMT", + "x-cache": "cp1050 hit (2), cp3009 miss (0), cp3008 frontend miss (0), HIT from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "age": "24084", + "x-cache-lookup": "HIT from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/emacs/emacs.png b/fedcode/static/pictogram-gh-pages/emacs/emacs.png new file mode 100644 index 0000000..15d1303 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/emacs/emacs.png differ diff --git a/fedcode/static/pictogram-gh-pages/erlang/erlang.json b/fedcode/static/pictogram-gh-pages/erlang/erlang.json new file mode 100644 index 0000000..39cbf90 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/erlang/erlang.json @@ -0,0 +1,26 @@ +{ + "name": "erlang", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/4/42/Erlang_logo.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Erlang_logo.png", + "headers": { + "x-object-meta-sha1base36": "9fnc3q5zjgdogh1ts5xghu6rcwweko4", + "last-modified": "Sat, 05 Oct 2013 04:15:57 GMT", + "etag": "4f325ef346b07fe5139af2f4b8d983a9", + "x-timestamp": "1380946556.00977", + "content-type": "image/png", + "x-trans-id": "tx9f0f1b6e8f784f5693e1a-00550949eb", + "x-varnish": "2031717282 1982343325, 1739242467 1477335145, 2301118869", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "13204", + "accept-ranges": "bytes", + "date": "Fri, 20 Mar 2015 13:52:03 GMT", + "age": "187416", + "connection": "keep-alive", + "x-cache": "cp1049 hit (5), cp3005 hit (46), cp3005 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/erlang/erlang.orig.png b/fedcode/static/pictogram-gh-pages/erlang/erlang.orig.png new file mode 100644 index 0000000..7a7f886 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/erlang/erlang.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/erlang/erlang.png b/fedcode/static/pictogram-gh-pages/erlang/erlang.png new file mode 100644 index 0000000..a420128 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/erlang/erlang.png differ diff --git a/fedcode/static/pictogram-gh-pages/f#/f#.json b/fedcode/static/pictogram-gh-pages/f#/f#.json new file mode 100644 index 0000000..5d7400c --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/f#/f#.json @@ -0,0 +1,35 @@ +{ + "name": "f#", + "source": { + "url": "https://avatars2.githubusercontent.com/u/485415?v=3&s=200", + "referrer": "https://github.com/fsharp", + "headers": { + "date": "Fri, 20 Mar 2015 13:50:03 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"f392a0ef9ac460573056b23fdc397be8a1f6cbea\"", + "last-modified": "Fri, 03 Oct 2014 14:25:35 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "87303463-c5d9-11e4-8c90-7ea81075bd94", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "6229", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6322-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Fri, 20 Mar 2015 13:55:03 GMT", + "source-age": "1009524", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/f#/f#.png b/fedcode/static/pictogram-gh-pages/f#/f#.png new file mode 100644 index 0000000..951ab53 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/f#/f#.png differ diff --git a/fedcode/static/pictogram-gh-pages/fortran/fortran.json b/fedcode/static/pictogram-gh-pages/fortran/fortran.json new file mode 100644 index 0000000..2d52e77 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/fortran/fortran.json @@ -0,0 +1,26 @@ +{ + "name": "fortran", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/b/b6/Fortran.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Fortran.png", + "headers": { + "x-object-meta-sha1base36": "5p0qf7xp6ghhgnidx3btraj2szpz7bd", + "last-modified": "Sun, 06 Oct 2013 08:19:50 GMT", + "etag": "98f202d06afc2058f7f0d098a34db798", + "x-timestamp": "1381047589.51325", + "content-type": "image/png", + "x-trans-id": "tx007ab3662eca4231bb4f5-00550c1218", + "x-varnish": "1954466162, 2342406270 2277457184, 53034675", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "60095", + "accept-ranges": "bytes", + "date": "Fri, 20 Mar 2015 22:30:46 GMT", + "age": "36223", + "connection": "keep-alive", + "x-cache": "cp1063 miss (0), cp3017 hit (6), cp3016 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/fortran/fortran.png b/fedcode/static/pictogram-gh-pages/fortran/fortran.png new file mode 100644 index 0000000..c965041 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/fortran/fortran.png differ diff --git a/fedcode/static/pictogram-gh-pages/game maker language/game maker language.json b/fedcode/static/pictogram-gh-pages/game maker language/game maker language.json new file mode 100644 index 0000000..d277d34 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/game maker language/game maker language.json @@ -0,0 +1,27 @@ +{ + "name": "game maker language", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/en/1/1b/The_game_maker_logo.png", + "referrer": "http://en.wikipedia.org/wiki/File:The_game_maker_logo.png", + "headers": { + "x-object-meta-sha1base36": "2uxp2dfbse28bst2ffelrzkgpcada2e", + "last-modified": "Tue, 02 Dec 2014 22:16:41 GMT", + "etag": "9f5dc5513b37e51de5e601ff2c8abc60", + "x-timestamp": "1417558600.71868", + "content-type": "image/png", + "x-trans-id": "tx5470b678f611415985562-00550d7590", + "x-varnish": "3187625487 3158568938, 1519968004 1492707793, 2825840377", + "content-length": "7316", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 20:56:48 GMT", + "age": "25985", + "x-cache": "cp1061 hit (5), cp3009 hit (11), cp3008 frontend miss (0), MISS from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/game maker language/game maker language.orig.png b/fedcode/static/pictogram-gh-pages/game maker language/game maker language.orig.png new file mode 100644 index 0000000..19767b3 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/game maker language/game maker language.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/game maker language/game maker language.png b/fedcode/static/pictogram-gh-pages/game maker language/game maker language.png new file mode 100644 index 0000000..482f757 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/game maker language/game maker language.png differ diff --git a/fedcode/static/pictogram-gh-pages/gem/gem.json b/fedcode/static/pictogram-gh-pages/gem/gem.json new file mode 100644 index 0000000..c0184d3 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/gem/gem.json @@ -0,0 +1,32 @@ +{ + "name": "rubygems", + "source": { + "url": "https://avatars1.githubusercontent.com/u/208761?v=3&s=200", + "referrer": "https://github.com/rubygems", + "headers": { + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/jpeg", + "etag": "\"f730df7964c5bf7044a913e758d216fb917f5fd4\"", + "last-modified": "Tue, 12 May 2015 02:52:03 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "c367552b-f880-11e4-8c16-ca7939fa6deb", + "x-xss-protection": "1; mode=block", + "content-length": "5719", + "accept-ranges": "bytes", + "date": "Tue, 19 May 2015 05:51:19 GMT", + "via": "1.1 varnish", + "connection": "keep-alive", + "x-served-by": "cache-ams4132-AMS", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Tue, 19 May 2015 05:56:19 GMT", + "source-age": "595415", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/gem/gem.png b/fedcode/static/pictogram-gh-pages/gem/gem.png new file mode 100644 index 0000000..8169068 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/gem/gem.png differ diff --git a/fedcode/static/pictogram-gh-pages/golang/golang.json b/fedcode/static/pictogram-gh-pages/golang/golang.json new file mode 100644 index 0000000..6733f0e --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/golang/golang.json @@ -0,0 +1,35 @@ +{ + "name": "go", + "source": { + "url": "https://avatars3.githubusercontent.com/u/4314092?v=3&s=200", + "referrer": "https://github.com/golang", + "headers": { + "date": "Sat, 14 Mar 2015 09:45:04 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"94a4d9e18dd02badeaeb772757d530218acdd677\"", + "last-modified": "Tue, 29 Apr 2014 15:16:14 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "73aa078e-c0fc-11e4-893a-e199b1f411c7", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "17189", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6325-LHR", + "x-cache": "HIT", + "x-cache-hits": "6", + "expires": "Sat, 14 Mar 2015 09:50:04 GMT", + "source-age": "1011180", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/golang/golang.png b/fedcode/static/pictogram-gh-pages/golang/golang.png new file mode 100644 index 0000000..7c0b78e Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/golang/golang.png differ diff --git a/fedcode/static/pictogram-gh-pages/groovy/groovy.json b/fedcode/static/pictogram-gh-pages/groovy/groovy.json new file mode 100644 index 0000000..813940f --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/groovy/groovy.json @@ -0,0 +1,34 @@ +{ + "name": "groovy", + "source": { + "url": "https://avatars3.githubusercontent.com/u/64846?v=3&s=200", + "referrer": "https://github.com/groovy", + "headers": { + "date": "Mon, 16 Mar 2015 23:03:12 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Mon, 19 Sep 2011 07:30:15 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "8ec6f362-cc30-11e4-8422-bbbe7f107df2", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "21804", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1128-LCY", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Mon, 16 Mar 2015 23:08:12 GMT", + "source-age": "27", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/groovy/groovy.png b/fedcode/static/pictogram-gh-pages/groovy/groovy.png new file mode 100644 index 0000000..727b5a5 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/groovy/groovy.png differ diff --git a/fedcode/static/pictogram-gh-pages/hack/hack.json b/fedcode/static/pictogram-gh-pages/hack/hack.json new file mode 100644 index 0000000..8329d8b --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/hack/hack.json @@ -0,0 +1,27 @@ +{ + "name": "hack", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/a/a0/Hack_-_Logo.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Hack_-_Logo.png", + "headers": { + "x-object-meta-sha1base36": "h35fejthfmy9xqfpcs62q6z3wp5omt7", + "last-modified": "Fri, 11 Jul 2014 09:02:48 GMT", + "etag": "9f0eee0e34ff13f0f5e1796566a76603", + "x-timestamp": "1405069367.28998", + "content-type": "image/png", + "x-trans-id": "tx7b847aa2cc2d468eaeee8-00550c046a", + "x-varnish": "3369011968 3323710527, 1063756058 990870583, 2262677973", + "content-length": "4827", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 09:43:16 GMT", + "age": "80074", + "x-cache": "cp1051 hit (9), cp3004 hit (18), cp3006 frontend miss (0), MISS from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/hack/hack.orig.png b/fedcode/static/pictogram-gh-pages/hack/hack.orig.png new file mode 100644 index 0000000..38ea021 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/hack/hack.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/hack/hack.png b/fedcode/static/pictogram-gh-pages/hack/hack.png new file mode 100644 index 0000000..2c041f4 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/hack/hack.png differ diff --git a/fedcode/static/pictogram-gh-pages/hackage/hackage.json b/fedcode/static/pictogram-gh-pages/hackage/hackage.json new file mode 100644 index 0000000..255744f --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/hackage/hackage.json @@ -0,0 +1,34 @@ +{ + "name": "hackage", + "source": { + "url": "https://avatars2.githubusercontent.com/u/450574?v=3&s=200", + "referrer": "https://github.com/haskell", + "headers": { + "date": "Mon, 16 Mar 2015 23:42:33 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Sat, 23 Oct 2010 23:35:06 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "0de2c5ca-cc36-11e4-811f-a7a1e9629941", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "13471", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6335-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Mon, 16 Mar 2015 23:47:33 GMT", + "source-age": "27", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/hackage/hackage.png b/fedcode/static/pictogram-gh-pages/hackage/hackage.png new file mode 100644 index 0000000..706b723 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/hackage/hackage.png differ diff --git a/fedcode/static/pictogram-gh-pages/handlebars/handlebars.json b/fedcode/static/pictogram-gh-pages/handlebars/handlebars.json new file mode 100644 index 0000000..4d7fbd6 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/handlebars/handlebars.json @@ -0,0 +1,27 @@ +{ + "name": "handlebars", + "source": { + "url": "http://handlebarsjs.com/images/handlebars_logo.png", + "referrer": "http://handlebarsjs.com/", + "headers": { + "server": "GitHub.com", + "content-type": "image/png", + "last-modified": "Tue, 10 Feb 2015 06:30:21 GMT", + "expires": "Thu, 12 Mar 2015 09:31:05 GMT", + "cache-control": "max-age=600", + "access-control-allow-origin": "*", + "content-length": "25946", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 19:42:14 GMT", + "age": "0", + "x-served-by": "cache-ams4145-AMS", + "x-cache": "HIT, MISS from cache_server", + "x-cache-hits": "1", + "x-timer": "S1426966934.602372,VS0,VE90", + "vary": "Accept-Encoding", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/handlebars/handlebars.orig.png b/fedcode/static/pictogram-gh-pages/handlebars/handlebars.orig.png new file mode 100644 index 0000000..b4918c1 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/handlebars/handlebars.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/handlebars/handlebars.png b/fedcode/static/pictogram-gh-pages/handlebars/handlebars.png new file mode 100644 index 0000000..b4918c1 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/handlebars/handlebars.png differ diff --git a/fedcode/static/pictogram-gh-pages/haskell/haskell.json b/fedcode/static/pictogram-gh-pages/haskell/haskell.json new file mode 100644 index 0000000..11e6a47 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/haskell/haskell.json @@ -0,0 +1,34 @@ +{ + "name": "haskell", + "source": { + "url": "https://avatars2.githubusercontent.com/u/450574?v=3&s=200", + "referrer": "https://github.com/haskell", + "headers": { + "date": "Sun, 15 Mar 2015 09:58:51 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Sat, 23 Oct 2010 23:35:06 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "1a07c08c-caf8-11e4-8739-c67a1e2d6a72", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "13471", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-ams4146-AMS", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Sun, 15 Mar 2015 10:03:51 GMT", + "source-age": "765", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/haskell/haskell.png b/fedcode/static/pictogram-gh-pages/haskell/haskell.png new file mode 100644 index 0000000..706b723 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/haskell/haskell.png differ diff --git a/fedcode/static/pictogram-gh-pages/haxe/haxe.json b/fedcode/static/pictogram-gh-pages/haxe/haxe.json new file mode 100644 index 0000000..d220a61 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/haxe/haxe.json @@ -0,0 +1,28 @@ +{ + "name": "haxe", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Haxe_logo.svg/200px-Haxe_logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Haxe_logo.svg", + "headers": { + "x-object-meta-sha1base36": "l1cgijtjx7vm1mhwcrafhrolscqboqd", + "content-disposition": "inline;filename*=UTF-8''Haxe_logo.svg.png", + "last-modified": "Mon, 26 Jan 2015 20:56:00 GMT", + "etag": "de1bd27446ee95f11e76d5f7bc475b33", + "x-timestamp": "1422305759.09582", + "content-type": "image/png", + "x-trans-id": "tx7b3e5487e39841c381a8b-00550dcad9", + "x-varnish": "3530181081, 3218751181 3218708352, 260505383", + "content-length": "8295", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 19:48:00 GMT", + "age": "23", + "x-cache": "cp1051 miss (0), cp3008 hit (1), cp3018 frontend miss (0), MISS from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/haxe/haxe.orig.png b/fedcode/static/pictogram-gh-pages/haxe/haxe.orig.png new file mode 100644 index 0000000..5f45d85 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/haxe/haxe.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/haxe/haxe.png b/fedcode/static/pictogram-gh-pages/haxe/haxe.png new file mode 100644 index 0000000..8223320 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/haxe/haxe.png differ diff --git a/fedcode/static/pictogram-gh-pages/hex/hex.json b/fedcode/static/pictogram-gh-pages/hex/hex.json new file mode 100644 index 0000000..2e1885f --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/hex/hex.json @@ -0,0 +1,33 @@ +{ + "name": "hex", + "source": { + "url": "https://avatars3.githubusercontent.com/u/6621265?v=3&s=200", + "referrer": "https://github.com/hexpm", + "headers": { + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"e6f29a15e37482ecd924ac4c85d84a7e1a1f4cd9\"", + "last-modified": "Thu, 03 Dec 2015 17:46:07 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-xss-protection": "1; mode=block", + "x-github-request-id": "B91F1315:62B9:2932F64:569199A5", + "content-length": "38133", + "accept-ranges": "bytes", + "date": "Sat, 09 Jan 2016 23:37:28 GMT", + "via": "1.1 varnish", + "connection": "close", + "x-served-by": "cache-lhr6335-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "access-control-allow-origin": "*", + "x-fastly-request-id": "1923d523d1a5f68ebaab2106f0873f4564120340", + "expires": "Sat, 09 Jan 2016 23:42:28 GMT", + "source-age": "18", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/hex/hex.png b/fedcode/static/pictogram-gh-pages/hex/hex.png new file mode 100644 index 0000000..caba666 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/hex/hex.png differ diff --git a/fedcode/static/pictogram-gh-pages/homebrew/homebrew.json b/fedcode/static/pictogram-gh-pages/homebrew/homebrew.json new file mode 100644 index 0000000..abb18b4 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/homebrew/homebrew.json @@ -0,0 +1,32 @@ +{ + "name": "homebrew", + "source": { + "url": "https://avatars2.githubusercontent.com/u/1503512?v=3&s=200", + "referrer": "https://github.com/homebrew", + "headers": { + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Sat, 07 Jun 2014 10:21:41 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-xss-protection": "1; mode=block", + "x-github-request-id": "B91F1221:3F69:D2FEA3B:56C0D2F8", + "content-length": "33056", + "accept-ranges": "bytes", + "date": "Sun, 14 Feb 2016 20:04:06 GMT", + "via": "1.1 varnish", + "connection": "close", + "x-served-by": "cache-lcy1135-LCY", + "x-cache": "HIT", + "x-cache-hits": "1", + "access-control-allow-origin": "*", + "x-fastly-request-id": "d2b0b79562e8079857220f6626ce9ec7d49843fc", + "expires": "Sun, 14 Feb 2016 20:09:06 GMT", + "source-age": "2750", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/homebrew/homebrew.png b/fedcode/static/pictogram-gh-pages/homebrew/homebrew.png new file mode 100644 index 0000000..ff8e716 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/homebrew/homebrew.png differ diff --git a/fedcode/static/pictogram-gh-pages/html/html.json b/fedcode/static/pictogram-gh-pages/html/html.json new file mode 100644 index 0000000..8509a09 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/html/html.json @@ -0,0 +1,18 @@ +{ + "name": "html", + "source": { + "url": "http://www.bobbyberberyan.com/wp-content/uploads/2012/03/HTML5CSS3Logos.svg", + "referrer": "http://www.bobbyberberyan.com/2012/03/html-5-css-3-logos/", + "headers": { + "date": "Sat, 14 Mar 2015 18:43:03 GMT", + "server": "Apache", + "last-modified": "Thu, 22 Mar 2012 17:12:34 GMT", + "etag": "\"ddc-4bbd80395e597\"", + "accept-ranges": "bytes", + "content-length": "3548", + "keep-alive": "timeout=5, max=100", + "connection": "Keep-Alive", + "content-type": "image/svg+xml" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/html/html.png b/fedcode/static/pictogram-gh-pages/html/html.png new file mode 100644 index 0000000..40ad510 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/html/html.png differ diff --git a/fedcode/static/pictogram-gh-pages/html/html.svg b/fedcode/static/pictogram-gh-pages/html/html.svg new file mode 100644 index 0000000..b0db13b --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/html/html.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fedcode/static/pictogram-gh-pages/inqlude/inqlude.json b/fedcode/static/pictogram-gh-pages/inqlude/inqlude.json new file mode 100644 index 0000000..1c23762 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/inqlude/inqlude.json @@ -0,0 +1,26 @@ +{ + "name": "inqlude", + "source": { + "url": "http://i.imgur.com/nxdK4ID.png", + "referrer": "https://inqlude.org/", + "headers": { + "last-modified": "Sun, 14 Feb 2016 12:40:57 GMT", + "etag": "\"ee2a41bad2b8bdea420394654fef7f7e\"", + "content-type": "image/png", + "fastly-debug-digest": "2ca73e610654849e26001be963ac45b7d1c9b112c74c8086d5a06b0fb77978fa", + "cache-control": "public, max-age=31536000", + "content-length": "5921", + "accept-ranges": "bytes", + "date": "Sun, 14 Feb 2016 12:42:13 GMT", + "age": "76", + "connection": "close", + "x-served-by": "cache-iad2144-IAD, cache-lhr6328-LHR", + "x-cache": "HIT, MISS", + "x-cache-hits": "1, 0", + "x-timer": "S1455453733.534115,VS0,VE76", + "access-control-allow-methods": "GET, OPTIONS", + "access-control-allow-origin": "*", + "server": "cat factory 1.0" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/inqlude/inqlude.png b/fedcode/static/pictogram-gh-pages/inqlude/inqlude.png new file mode 100644 index 0000000..52f4c93 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/inqlude/inqlude.png differ diff --git a/fedcode/static/pictogram-gh-pages/jam/jam.json b/fedcode/static/pictogram-gh-pages/jam/jam.json new file mode 100644 index 0000000..7fe64dd --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/jam/jam.json @@ -0,0 +1,21 @@ +{ + "name": "jam", + "source": { + "url": "http://jamjs.org/img/jam_large.png", + "referrer": "http://jamjs.org/", + "headers": { + "server": "CouchDB/1.2.0 (Erlang OTP/R15B01)", + "etag": "\"X2b5KkOOeVZgrc1YLa8kYg==\"", + "date": "Sat, 21 Mar 2015 09:53:45 GMT", + "content-type": "image/png", + "content-md5": "X2b5KkOOeVZgrc1YLa8kYg==", + "content-length": "8088", + "cache-control": "must-revalidate", + "accept-ranges": "bytes", + "x-cache": "MISS from cache_server", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/jam/jam.orig.png b/fedcode/static/pictogram-gh-pages/jam/jam.orig.png new file mode 100644 index 0000000..89af2c3 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/jam/jam.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/jam/jam.png b/fedcode/static/pictogram-gh-pages/jam/jam.png new file mode 100644 index 0000000..6a3d268 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/jam/jam.png differ diff --git a/fedcode/static/pictogram-gh-pages/java/java.json b/fedcode/static/pictogram-gh-pages/java/java.json new file mode 100644 index 0000000..5daa4a8 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/java/java.json @@ -0,0 +1,26 @@ +{ + "name": "java", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Java_logo_and_wordmark.svg/500px-Java_logo_and_wordmark.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Java_logo_and_wordmark.svg", + "headers": { + "x-object-meta-sha1base36": "pwh107guwerk22u42wk4fgl5xlzn0jo", + "last-modified": "Thu, 31 Oct 2013 06:04:09 GMT", + "etag": "d0a95bc97c5792f6db1a4f3538ef0cd6", + "x-timestamp": "1383199448.25672", + "content-type": "image/png", + "x-trans-id": "tx91ec8e3a835a414eb562b-0055060cb8", + "x-varnish": "2265994897, 1099177107, 2216060245 2215958784", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "43989", + "accept-ranges": "bytes", + "date": "Sun, 15 Mar 2015 22:51:18 GMT", + "age": "46", + "connection": "keep-alive", + "x-cache": "cp1064 miss (0), cp3005 miss (0), cp3007 frontend hit (1)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/java/java.orig.png b/fedcode/static/pictogram-gh-pages/java/java.orig.png new file mode 100644 index 0000000..524e16f Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/java/java.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/java/java.png b/fedcode/static/pictogram-gh-pages/java/java.png new file mode 100644 index 0000000..0f9bc3d Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/java/java.png differ diff --git a/fedcode/static/pictogram-gh-pages/javascript/javascript.json b/fedcode/static/pictogram-gh-pages/javascript/javascript.json new file mode 100644 index 0000000..cd24593 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/javascript/javascript.json @@ -0,0 +1,35 @@ +{ + "name": "javascript", + "source": { + "url": "https://avatars2.githubusercontent.com/u/1782180?v=3&s=200", + "referrer": "https://github.com/javascript", + "headers": { + "date": "Sat, 14 Mar 2015 18:16:20 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"d3aea59fec2c937e534dfe6a0629346901fb4a06\"", + "last-modified": "Fri, 28 Mar 2014 14:33:48 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "ddf81d16-ca75-11e4-81e4-eaff48c4ed6c", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "7978", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6335-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Sat, 14 Mar 2015 18:21:20 GMT", + "source-age": "149", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/javascript/javascript.png b/fedcode/static/pictogram-gh-pages/javascript/javascript.png new file mode 100644 index 0000000..1d129cb Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/javascript/javascript.png differ diff --git a/fedcode/static/pictogram-gh-pages/julia/julia.json b/fedcode/static/pictogram-gh-pages/julia/julia.json new file mode 100644 index 0000000..7e22181 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/julia/julia.json @@ -0,0 +1,34 @@ +{ + "name": "julia", + "source": { + "url": "https://avatars2.githubusercontent.com/u/743164?v=3&s=200", + "referrer": "https://github.com/JuliaLang", + "headers": { + "date": "Mon, 23 Mar 2015 20:52:13 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Tue, 05 Feb 2013 04:28:55 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "2aaeb16d-d19e-11e4-8411-c962c4f9c5f4", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "10776", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-ams4146-AMS", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Mon, 23 Mar 2015 20:57:13 GMT", + "source-age": "136", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/julia/julia.png b/fedcode/static/pictogram-gh-pages/julia/julia.png new file mode 100644 index 0000000..c74ada8 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/julia/julia.png differ diff --git a/fedcode/static/pictogram-gh-pages/livescript/livescript.json b/fedcode/static/pictogram-gh-pages/livescript/livescript.json new file mode 100644 index 0000000..ee46130 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/livescript/livescript.json @@ -0,0 +1,27 @@ +{ + "name": "livescript", + "source": { + "url": "http://livescript.net/images/icon.png", + "referrer": "http://livescript.net/", + "headers": { + "date": "Sat, 21 Mar 2015 19:59:43 GMT", + "content-type": "image/png", + "content-length": "1014", + "set-cookie": [ + "__cfduid=dc08b9d32eaa07436c6c9e6be50534ed81426967983; expires=Sun, 20-Mar-16 19:59:43 GMT; path=/; domain=.livescript.net; HttpOnly" + ], + "last-modified": "Tue, 24 Feb 2015 02:39:36 GMT", + "expires": "Thu, 26 Mar 2015 19:59:43 GMT", + "cache-control": "public, max-age=432000", + "access-control-allow-origin": "*", + "cf-cache-status": "HIT", + "accept-ranges": "bytes", + "server": "cloudflare-nginx", + "cf-ray": "1cac3d2691410b7b-LHR", + "x-cache": "MISS from cache_server", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/livescript/livescript.orig.png b/fedcode/static/pictogram-gh-pages/livescript/livescript.orig.png new file mode 100644 index 0000000..f7eacec Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/livescript/livescript.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/livescript/livescript.png b/fedcode/static/pictogram-gh-pages/livescript/livescript.png new file mode 100644 index 0000000..8c4fdfc Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/livescript/livescript.png differ diff --git a/fedcode/static/pictogram-gh-pages/lua/lua.json b/fedcode/static/pictogram-gh-pages/lua/lua.json new file mode 100644 index 0000000..4a3865e --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/lua/lua.json @@ -0,0 +1,34 @@ +{ + "name": "lua", + "source": { + "url": "https://avatars0.githubusercontent.com/u/2319114?v=3&s=200", + "referrer": "https://github.com/lua", + "headers": { + "date": "Tue, 17 Mar 2015 00:14:36 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Sun, 07 Jul 2013 00:20:33 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "98866c33-cc3a-11e4-8491-cf2de38bf09a", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "11885", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1132-LCY", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Tue, 17 Mar 2015 00:19:36 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/lua/lua.png b/fedcode/static/pictogram-gh-pages/lua/lua.png new file mode 100644 index 0000000..54b40f1 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/lua/lua.png differ diff --git a/fedcode/static/pictogram-gh-pages/make/make.json b/fedcode/static/pictogram-gh-pages/make/make.json new file mode 100644 index 0000000..275f3ef --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/make/make.json @@ -0,0 +1,27 @@ +{ + "name": "make", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/en/thumb/2/22/Heckert_GNU_white.svg/200px-Heckert_GNU_white.svg.png", + "referrer": "http://en.wikipedia.org/wiki/GNU_build_system", + "headers": { + "x-object-meta-sha1base36": "jphn9l2ntkyph5cpnkdqw3018978wpk", + "last-modified": "Fri, 18 Oct 2013 02:15:00 GMT", + "etag": "24fb20b34ca8d97ca3cf894f39714771", + "x-timestamp": "1382062499.97337", + "content-type": "image/png", + "x-trans-id": "tx29f08de73cb241fa9ee53-00550d11ac", + "x-varnish": "3492002593 3453183821, 2449133075 2409851222, 260742103", + "content-length": "20971", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 20:22:49 GMT", + "x-cache": "cp1051 hit (5), cp3017 hit (7), cp3017 frontend miss (0), HIT from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "age": "49536", + "x-cache-lookup": "HIT from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/make/make.orig.png b/fedcode/static/pictogram-gh-pages/make/make.orig.png new file mode 100644 index 0000000..8ee2a03 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/make/make.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/make/make.png b/fedcode/static/pictogram-gh-pages/make/make.png new file mode 100644 index 0000000..8f1c660 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/make/make.png differ diff --git a/fedcode/static/pictogram-gh-pages/makefile/makefile.json b/fedcode/static/pictogram-gh-pages/makefile/makefile.json new file mode 100644 index 0000000..635e86d --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/makefile/makefile.json @@ -0,0 +1,27 @@ +{ + "name": "makefile", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/en/thumb/2/22/Heckert_GNU_white.svg/200px-Heckert_GNU_white.svg.png", + "referrer": "http://en.wikipedia.org/wiki/GNU_build_system", + "headers": { + "x-object-meta-sha1base36": "jphn9l2ntkyph5cpnkdqw3018978wpk", + "last-modified": "Fri, 18 Oct 2013 02:15:00 GMT", + "etag": "24fb20b34ca8d97ca3cf894f39714771", + "x-timestamp": "1382062499.97337", + "content-type": "image/png", + "x-trans-id": "tx29f08de73cb241fa9ee53-00550d11ac", + "x-varnish": "3492002593 3453183821, 2449133075 2409851222, 260742103", + "content-length": "20971", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 20:22:49 GMT", + "x-cache": "cp1051 hit (5), cp3017 hit (7), cp3017 frontend miss (0), HIT from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "age": "49536", + "x-cache-lookup": "HIT from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} diff --git a/fedcode/static/pictogram-gh-pages/makefile/makefile.orig.png b/fedcode/static/pictogram-gh-pages/makefile/makefile.orig.png new file mode 100644 index 0000000..8ee2a03 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/makefile/makefile.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/makefile/makefile.png b/fedcode/static/pictogram-gh-pages/makefile/makefile.png new file mode 100644 index 0000000..8f1c660 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/makefile/makefile.png differ diff --git a/fedcode/static/pictogram-gh-pages/maven/maven.json b/fedcode/static/pictogram-gh-pages/maven/maven.json new file mode 100644 index 0000000..6f06fb4 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/maven/maven.json @@ -0,0 +1,26 @@ +{ + "name": "maven", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Maven_logo.svg/200px-Maven_logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Maven_logo.svg", + "headers": { + "x-object-meta-sha1base36": "05bje88vsirv1p1ba9k8ocl7wix6lx0", + "last-modified": "Wed, 23 Oct 2013 13:45:32 GMT", + "etag": "2ed277e3826f0d1eea4212fef7e6d5c2", + "x-timestamp": "1382535931.78982", + "content-type": "image/png", + "x-trans-id": "txb667e00095384da29b894-005505ef03", + "x-varnish": "2073997766 2057322608, 2031911708 2031659727, 1252298227", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "2269", + "accept-ranges": "bytes", + "date": "Sun, 15 Mar 2015 22:49:35 GMT", + "age": "7548", + "connection": "keep-alive", + "x-cache": "cp1062 hit (1), cp3016 hit (1), cp3010 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/maven/maven.orig.png b/fedcode/static/pictogram-gh-pages/maven/maven.orig.png new file mode 100644 index 0000000..e781698 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/maven/maven.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/maven/maven.png b/fedcode/static/pictogram-gh-pages/maven/maven.png new file mode 100644 index 0000000..97f4024 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/maven/maven.png differ diff --git a/fedcode/static/pictogram-gh-pages/meteor/meteor.json b/fedcode/static/pictogram-gh-pages/meteor/meteor.json new file mode 100644 index 0000000..faacf23 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/meteor/meteor.json @@ -0,0 +1,35 @@ +{ + "name": "meteor", + "source": { + "url": "https://avatars3.githubusercontent.com/u/789528?v=3&s=200", + "referrer": "https://github.com/meteor", + "headers": { + "date": "Mon, 16 Mar 2015 23:41:06 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"ea3ad9c5a3e51faaa74685e71f40e29c77367e37\"", + "last-modified": "Tue, 28 Oct 2014 18:20:15 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "27ae5a03-c94a-11e4-8967-0c0973f56157", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "3926", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1129-LCY", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Mon, 16 Mar 2015 23:46:06 GMT", + "source-age": "321160", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/meteor/meteor.png b/fedcode/static/pictogram-gh-pages/meteor/meteor.png new file mode 100644 index 0000000..6efa588 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/meteor/meteor.png differ diff --git a/fedcode/static/pictogram-gh-pages/nimble/nimble.json b/fedcode/static/pictogram-gh-pages/nimble/nimble.json new file mode 100644 index 0000000..099c1f3 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/nimble/nimble.json @@ -0,0 +1,35 @@ +{ + "name": "nimble", + "source": { + "url": "https://avatars3.githubusercontent.com/u/603863?v=3&s=200", + "referrer": "https://github.com/nim-lang", + "headers": { + "date": "Tue, 17 Mar 2015 21:33:37 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"a513c8a1ca00d2b756d1aab7dd2929cdb7ae34a6\"", + "last-modified": "Thu, 05 Mar 2015 22:44:09 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "57a175a2-c97f-11e4-8e1f-3e2a3c6c6171", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "113754", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1124-LCY", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Tue, 17 Mar 2015 21:38:37 GMT", + "source-age": "377067", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/nimble/nimble.png b/fedcode/static/pictogram-gh-pages/nimble/nimble.png new file mode 100644 index 0000000..20cde49 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/nimble/nimble.png differ diff --git a/fedcode/static/pictogram-gh-pages/nimrod/nimrod.json b/fedcode/static/pictogram-gh-pages/nimrod/nimrod.json new file mode 100644 index 0000000..95b2454 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/nimrod/nimrod.json @@ -0,0 +1,35 @@ +{ + "name": "nimrod", + "source": { + "url": "https://avatars3.githubusercontent.com/u/603863?v=3&s=200", + "referrer": "https://github.com/nim-lang", + "headers": { + "date": "Tue, 17 Mar 2015 21:34:35 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"a513c8a1ca00d2b756d1aab7dd2929cdb7ae34a6\"", + "last-modified": "Thu, 05 Mar 2015 22:44:09 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "0913fffe-c3d2-11e4-8f71-74323f6a3667", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "113754", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-ams4143-AMS", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Tue, 17 Mar 2015 21:39:35 GMT", + "source-age": "1001316", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/nimrod/nimrod.png b/fedcode/static/pictogram-gh-pages/nimrod/nimrod.png new file mode 100644 index 0000000..20cde49 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/nimrod/nimrod.png differ diff --git a/fedcode/static/pictogram-gh-pages/npm/npm.json b/fedcode/static/pictogram-gh-pages/npm/npm.json new file mode 100644 index 0000000..99b6b8f --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/npm/npm.json @@ -0,0 +1,34 @@ +{ + "name": "npm", + "source": { + "url": "https://avatars2.githubusercontent.com/u/6078720?v=3&s=200", + "referrer": "https://github.com/npm", + "headers": { + "date": "Sun, 15 Mar 2015 10:16:20 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Wed, 11 Dec 2013 07:32:31 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "5318af5c-cafc-11e4-8bbf-e2ba349307bc", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "6569", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1127-LCY", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sun, 15 Mar 2015 10:21:20 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/npm/npm.png b/fedcode/static/pictogram-gh-pages/npm/npm.png new file mode 100644 index 0000000..cbea0a5 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/npm/npm.png differ diff --git a/fedcode/static/pictogram-gh-pages/nuget/nuget.json b/fedcode/static/pictogram-gh-pages/nuget/nuget.json new file mode 100644 index 0000000..6c0b72b --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/nuget/nuget.json @@ -0,0 +1,34 @@ +{ + "name": "nuget", + "source": { + "url": "https://avatars3.githubusercontent.com/u/968310?v=3&s=200", + "referrer": "https://github.com/nuget", + "headers": { + "date": "Sun, 15 Mar 2015 10:35:13 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Mon, 24 Oct 2011 23:18:07 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "f6c154d9-cafe-11e4-8229-55b0e70df56b", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "24672", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-ams4123-AMS", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sun, 15 Mar 2015 10:40:13 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/nuget/nuget.png b/fedcode/static/pictogram-gh-pages/nuget/nuget.png new file mode 100644 index 0000000..f217e2a Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/nuget/nuget.png differ diff --git a/fedcode/static/pictogram-gh-pages/packagist/packagist.json b/fedcode/static/pictogram-gh-pages/packagist/packagist.json new file mode 100644 index 0000000..dabadb8 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/packagist/packagist.json @@ -0,0 +1,34 @@ +{ + "name": "packagist", + "source": { + "url": "https://avatars3.githubusercontent.com/u/5014846?v=3&s=200", + "referrer": "https://github.com/packagist", + "headers": { + "date": "Sun, 15 Mar 2015 10:17:29 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Tue, 16 Jul 2013 09:43:29 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "7c5f0873-cafc-11e4-8ad7-436f9ae371f7", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "33759", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-fra1244-FRA", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sun, 15 Mar 2015 10:22:29 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/packagist/packagist.png b/fedcode/static/pictogram-gh-pages/packagist/packagist.png new file mode 100644 index 0000000..1c6b55e Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/packagist/packagist.png differ diff --git a/fedcode/static/pictogram-gh-pages/perl/perl.gif b/fedcode/static/pictogram-gh-pages/perl/perl.gif new file mode 100644 index 0000000..ffbc9cb Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/perl/perl.gif differ diff --git a/fedcode/static/pictogram-gh-pages/perl/perl.json b/fedcode/static/pictogram-gh-pages/perl/perl.json new file mode 100644 index 0000000..3e943cc --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/perl/perl.json @@ -0,0 +1,18 @@ +{ + "name": "perl", + "source": { + "url": "http://www.onlamp.com/images/perl/camel.gif", + "referrer": "http://www.onlamp.com/pub/a/oreilly/perl/usage/", + "headers": { + "server": "Apache", + "last-modified": "Fri, 24 Jan 2003 20:01:36 GMT", + "accept-ranges": "bytes", + "content-length": "4265", + "content-type": "image/gif", + "cache-control": "max-age=86334", + "expires": "Sat, 21 Mar 2015 22:49:00 GMT", + "date": "Fri, 20 Mar 2015 22:50:06 GMT", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/perl/perl.png b/fedcode/static/pictogram-gh-pages/perl/perl.png new file mode 100644 index 0000000..8998e7b Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/perl/perl.png differ diff --git a/fedcode/static/pictogram-gh-pages/perl6/perl6.json b/fedcode/static/pictogram-gh-pages/perl6/perl6.json new file mode 100644 index 0000000..3839e95 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/perl6/perl6.json @@ -0,0 +1,26 @@ +{ + "name": "perl6", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Camelia.svg/200px-Camelia.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Camelia.svg", + "headers": { + "last-modified": "Wed, 30 Oct 2013 01:14:29 GMT", + "etag": "edd268c201ec56a28a618d7e9955e995", + "x-timestamp": "1383095668.99091", + "content-type": "image/png", + "x-trans-id": "tx8db83b396e70478f95e64-00550d6ce3", + "x-varnish": "1935352789 1919981991, 3318640027 3274448579, 2392106862", + "content-length": "13887", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 21:08:37 GMT", + "x-cache": "cp1050 hit (25), cp3007 hit (65), cp3006 frontend miss (0), HIT from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "age": "28946", + "x-cache-lookup": "HIT from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/perl6/perl6.png b/fedcode/static/pictogram-gh-pages/perl6/perl6.png new file mode 100644 index 0000000..ec92a83 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/perl6/perl6.png differ diff --git a/fedcode/static/pictogram-gh-pages/php/php.json b/fedcode/static/pictogram-gh-pages/php/php.json new file mode 100644 index 0000000..93a8f56 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/php/php.json @@ -0,0 +1,34 @@ +{ + "name": "php", + "source": { + "url": "https://avatars3.githubusercontent.com/u/25158?v=3&s=200", + "referrer": "https://github.com/php", + "headers": { + "date": "Sat, 14 Mar 2015 16:11:57 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Tue, 15 Oct 2013 14:10:47 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "55f44d3e-ca64-11e4-8837-566d0201505c", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "15299", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6321-LHR", + "x-cache": "HIT", + "x-cache-hits": "2", + "expires": "Sat, 14 Mar 2015 16:16:57 GMT", + "source-age": "216", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/php/php.png b/fedcode/static/pictogram-gh-pages/php/php.png new file mode 100644 index 0000000..f9b0fe7 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/php/php.png differ diff --git a/fedcode/static/pictogram-gh-pages/platformio/platformio.json b/fedcode/static/pictogram-gh-pages/platformio/platformio.json new file mode 100644 index 0000000..9ab96a2 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/platformio/platformio.json @@ -0,0 +1,32 @@ +{ + "name": "platformio", + "source": { + "url": "https://avatars2.githubusercontent.com/u/11621357?v=3&s=200", + "referrer": "https://github.com/platformio", + "headers": { + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"5881cb5ccf08f6a95d85eb34a848454984275a4b\"", + "last-modified": "Sat, 27 Jun 2015 15:00:39 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "b44e737d-1da2-11e5-89bf-2c77d4e0b3c8", + "x-xss-protection": "1; mode=block", + "content-length": "7358", + "accept-ranges": "bytes", + "date": "Sun, 28 Jun 2015 14:33:55 GMT", + "via": "1.1 varnish", + "connection": "keep-alive", + "x-served-by": "cache-lcy1120-LCY", + "x-cache": "MISS", + "x-cache-hits": "0", + "access-control-allow-origin": "*", + "expires": "Sun, 28 Jun 2015 14:38:55 GMT", + "source-age": "0", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/platformio/platformio.png b/fedcode/static/pictogram-gh-pages/platformio/platformio.png new file mode 100644 index 0000000..e9ac61a Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/platformio/platformio.png differ diff --git a/fedcode/static/pictogram-gh-pages/powershell/powershell.json b/fedcode/static/pictogram-gh-pages/powershell/powershell.json new file mode 100644 index 0000000..951c8b7 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/powershell/powershell.json @@ -0,0 +1,35 @@ +{ + "name": "powershell", + "source": { + "url": "https://avatars0.githubusercontent.com/u/11524380?v=3&s=200", + "referrer": "https://github.com/powershell", + "headers": { + "date": "Fri, 20 Mar 2015 13:50:44 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"e39dde03263468f440b359ec09095bdbfee92fd6\"", + "last-modified": "Tue, 17 Mar 2015 16:25:40 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "1aa8647a-cf08-11e4-83bc-9823d777ddf9", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "18816", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1133-LCY", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Fri, 20 Mar 2015 13:55:44 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/powershell/powershell.png b/fedcode/static/pictogram-gh-pages/powershell/powershell.png new file mode 100644 index 0000000..4e3afee Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/powershell/powershell.png differ diff --git a/fedcode/static/pictogram-gh-pages/pub/pub.json b/fedcode/static/pictogram-gh-pages/pub/pub.json new file mode 100644 index 0000000..2ff74c8 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/pub/pub.json @@ -0,0 +1,35 @@ +{ + "name": "pub", + "source": { + "url": "https://avatars3.githubusercontent.com/u/1609975?v=3&s=200", + "referrer": "https://github.com/dart-lang", + "headers": { + "date": "Tue, 17 Mar 2015 21:35:25 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"c5a357d3e7aa9966f25cb6ae2c53724064ba47a6\"", + "last-modified": "Tue, 29 Apr 2014 15:18:02 GMT", + "strict-transport-security": "max-age=2592000", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "f091f12f-7283-11e4-8b11-58e94b704dee", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "29207", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1120-LCY", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Tue, 17 Mar 2015 21:40:25 GMT", + "source-age": "9940953", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/pub/pub.png b/fedcode/static/pictogram-gh-pages/pub/pub.png new file mode 100644 index 0000000..d378fd8 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/pub/pub.png differ diff --git a/fedcode/static/pictogram-gh-pages/puppet/puppet.json b/fedcode/static/pictogram-gh-pages/puppet/puppet.json new file mode 100644 index 0000000..60d56b4 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/puppet/puppet.json @@ -0,0 +1,34 @@ +{ + "name": "puppet", + "source": { + "url": "https://avatars3.githubusercontent.com/u/234268?v=3&s=200", + "referrer": "https://github.com/puppetlabs", + "headers": { + "date": "Fri, 20 Mar 2015 22:40:44 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Fri, 09 Jul 2010 17:49:51 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "9c8b3fc5-cf4c-11e4-8ea4-a165337637e8", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "16770", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6335-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Fri, 20 Mar 2015 22:45:44 GMT", + "source-age": "2377", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/puppet/puppet.png b/fedcode/static/pictogram-gh-pages/puppet/puppet.png new file mode 100644 index 0000000..ec61ad6 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/puppet/puppet.png differ diff --git a/fedcode/static/pictogram-gh-pages/purescript/purescript.json b/fedcode/static/pictogram-gh-pages/purescript/purescript.json new file mode 100644 index 0000000..ef41b9b --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/purescript/purescript.json @@ -0,0 +1,35 @@ +{ + "name": "purescript", + "source": { + "url": "https://avatars3.githubusercontent.com/u/6556677?v=3&s=200", + "referrer": "https://github.com/purescript", + "headers": { + "date": "Fri, 20 Mar 2015 13:47:34 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"556d5792e43131aae9d4e04f373056977b16498d\"", + "last-modified": "Sun, 04 May 2014 19:45:39 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "ebc1d9de-abfe-11e4-81a8-1fd0c4853f23", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "1043", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6334-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Fri, 20 Mar 2015 13:52:34 GMT", + "source-age": "3852044", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/purescript/purescript.png b/fedcode/static/pictogram-gh-pages/purescript/purescript.png new file mode 100644 index 0000000..c21c0c8 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/purescript/purescript.png differ diff --git a/fedcode/static/pictogram-gh-pages/pypi/pypi.json b/fedcode/static/pictogram-gh-pages/pypi/pypi.json new file mode 100644 index 0000000..e529d66 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/pypi/pypi.json @@ -0,0 +1,34 @@ +{ + "name": "pypi", + "source": { + "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Python-logo-notext.svg/1024px-Python-logo-notext.svg.png", + "referrer": "wikipedia", + "headers": { + "server": "nginx/1.9.4", + "date": "Tue, 23 Feb 2016 18:48:11 GMT", + "content-type": "image/png", + "content-length": "73663", + "connection": "close", + "x-object-meta-sha1base36": "b7r64q960agb9lzuxhj43w7t9nbx6m2", + "content-disposition": "inline;filename*=UTF-8''Python-logo-notext.svg.png", + "last-modified": "Thu, 28 Aug 2014 14:31:18 GMT", + "etag": "ed666327dd3ce274d94f2b3547155891", + "x-timestamp": "1409236277.65046", + "x-trans-id": "txdcd1f30413644a95a4e96-0056cab8c7", + "x-varnish": "174832178 92364174, 3852301110 3599779678, 3631330066 3630947417", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "accept-ranges": "bytes", + "age": "127140", + "x-cache": "cp1074 hit(30), cp3046 hit(117), cp3048 frontend hit(2)", + "strict-transport-security": "max-age=31536000", + "set-cookie": [ + "WMF-Last-Access=23-Feb-2016;Path=/;HttpOnly;Expires=Sat, 26 Mar 2016 12:00:00 GMT" + ], + "x-analytics": "https=1;nocookies=1", + "x-client-ip": "81.187.162.80", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/pypi/pypi.png b/fedcode/static/pictogram-gh-pages/pypi/pypi.png new file mode 100644 index 0000000..4c5d5ee Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/pypi/pypi.png differ diff --git a/fedcode/static/pictogram-gh-pages/python/python.json b/fedcode/static/pictogram-gh-pages/python/python.json new file mode 100644 index 0000000..4462bba --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/python/python.json @@ -0,0 +1,34 @@ +{ + "name": "python", + "source": { + "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Python-logo-notext.svg/1024px-Python-logo-notext.svg.png", + "referrer": "wikipedia", + "headers": { + "server": "nginx/1.9.4", + "date": "Tue, 23 Feb 2016 18:48:05 GMT", + "content-type": "image/png", + "content-length": "73663", + "connection": "close", + "x-object-meta-sha1base36": "b7r64q960agb9lzuxhj43w7t9nbx6m2", + "content-disposition": "inline;filename*=UTF-8''Python-logo-notext.svg.png", + "last-modified": "Thu, 28 Aug 2014 14:31:18 GMT", + "etag": "ed666327dd3ce274d94f2b3547155891", + "x-timestamp": "1409236277.65046", + "x-trans-id": "txdcd1f30413644a95a4e96-0056cab8c7", + "x-varnish": "174832178 92364174, 3852301110 3599779678, 3631305694 3630947417", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "accept-ranges": "bytes", + "age": "127134", + "x-cache": "cp1074 hit(30), cp3046 hit(117), cp3048 frontend hit(1)", + "strict-transport-security": "max-age=31536000", + "set-cookie": [ + "WMF-Last-Access=23-Feb-2016;Path=/;HttpOnly;Expires=Sat, 26 Mar 2016 12:00:00 GMT" + ], + "x-analytics": "https=1;nocookies=1", + "x-client-ip": "81.187.162.80", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/python/python.png b/fedcode/static/pictogram-gh-pages/python/python.png new file mode 100644 index 0000000..4c5d5ee Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/python/python.png differ diff --git a/fedcode/static/pictogram-gh-pages/r/r.json b/fedcode/static/pictogram-gh-pages/r/r.json new file mode 100644 index 0000000..f85eb28 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/r/r.json @@ -0,0 +1,28 @@ +{ + "name": "r", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/R_logo.svg/200px-R_logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:R_logo.svg", + "headers": { + "x-object-meta-sha1base36": "4k5u08r0xmrgw9as845n2yxbcfx2ohl", + "content-disposition": "inline;filename*=UTF-8''R_logo.svg.png", + "last-modified": "Wed, 24 Sep 2014 00:32:30 GMT", + "etag": "4d2a3c398e6dfebc8db0049b2d74055b", + "x-timestamp": "1411518749.34215", + "content-type": "image/png", + "x-trans-id": "tx2f2ab271ce2e4e2686449-00550c4ed7", + "x-varnish": "2379257310 2363119544, 2379253562 2317379629, 3417700854", + "content-length": "35295", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 10:07:47 GMT", + "x-cache": "cp1049 hit (121), cp3017 hit (351), cp3004 frontend miss (0), HIT from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "age": "62518", + "x-cache-lookup": "HIT from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/r/r.png b/fedcode/static/pictogram-gh-pages/r/r.png new file mode 100644 index 0000000..1d4fcd7 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/r/r.png differ diff --git a/fedcode/static/pictogram-gh-pages/ruby/ruby.json b/fedcode/static/pictogram-gh-pages/ruby/ruby.json new file mode 100644 index 0000000..f36a072 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/ruby/ruby.json @@ -0,0 +1,34 @@ +{ + "name": "ruby", + "source": { + "url": "https://avatars0.githubusercontent.com/u/210414?v=3&s=200", + "referrer": "https://github.com/ruby", + "headers": { + "date": "Sat, 14 Mar 2015 10:15:13 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Wed, 19 Oct 2011 12:21:53 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "010585d7-ca33-11e4-86eb-0f0eb73790a9", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "32184", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1125-LCY", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sat, 14 Mar 2015 10:20:13 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/ruby/ruby.orig.png b/fedcode/static/pictogram-gh-pages/ruby/ruby.orig.png new file mode 100644 index 0000000..8f69995 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/ruby/ruby.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/ruby/ruby.png b/fedcode/static/pictogram-gh-pages/ruby/ruby.png new file mode 100644 index 0000000..eeaadec Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/ruby/ruby.png differ diff --git a/fedcode/static/pictogram-gh-pages/rust/rust.json b/fedcode/static/pictogram-gh-pages/rust/rust.json new file mode 100644 index 0000000..9cf9c69 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/rust/rust.json @@ -0,0 +1,34 @@ +{ + "name": "rust", + "source": { + "url": "https://avatars1.githubusercontent.com/u/5430905?v=3&s=200", + "referrer": "https://github.com/rust-lang", + "headers": { + "date": "Mon, 16 Mar 2015 22:21:44 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Fri, 10 Jan 2014 04:29:00 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "c11a7bc3-cc2a-11e4-89be-4556c9ef9d95", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "15811", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lcy1125-LCY", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Mon, 16 Mar 2015 22:26:44 GMT", + "source-age": "32", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/rust/rust.png b/fedcode/static/pictogram-gh-pages/rust/rust.png new file mode 100644 index 0000000..b8a13aa Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/rust/rust.png differ diff --git a/fedcode/static/pictogram-gh-pages/scala/scala.json b/fedcode/static/pictogram-gh-pages/scala/scala.json new file mode 100644 index 0000000..876cbdc --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/scala/scala.json @@ -0,0 +1,35 @@ +{ + "name": "scala", + "source": { + "url": "https://avatars1.githubusercontent.com/u/57059?v=3&s=200", + "referrer": "https://github.com/scala", + "headers": { + "date": "Sat, 14 Mar 2015 18:16:57 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"b33c1827875a985cc1c32ad87377a1aad4afa2e5\"", + "last-modified": "Mon, 14 Apr 2014 14:09:58 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "f36a2b9c-b4f4-11e4-86b5-bc82ab0ff7bb", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "13018", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6326-LHR", + "x-cache": "HIT", + "x-cache-hits": "1", + "expires": "Sat, 14 Mar 2015 18:21:57 GMT", + "source-age": "2364528", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/scala/scala.png b/fedcode/static/pictogram-gh-pages/scala/scala.png new file mode 100644 index 0000000..2ff9c47 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/scala/scala.png differ diff --git a/fedcode/static/pictogram-gh-pages/scheme/scheme.json b/fedcode/static/pictogram-gh-pages/scheme/scheme.json new file mode 100644 index 0000000..0e7ed75 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/scheme/scheme.json @@ -0,0 +1,25 @@ +{ + "name": "scheme", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Lambda_lc.svg/200px-Lambda_lc.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Lambda_lc.svg", + "headers": { + "last-modified": "Wed, 23 Oct 2013 08:41:09 GMT", + "etag": "d5e647ec2c09dd8d78e4dd9e17af985c", + "x-timestamp": "1382517668.24772", + "content-type": "image/png", + "x-trans-id": "tx4e212ff236e447819fd40-00550a6320", + "x-varnish": "2865338136 2830755169, 2833241096 2603490708, 2397153080", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "3625", + "accept-ranges": "bytes", + "date": "Fri, 20 Mar 2015 22:27:26 GMT", + "age": "146350", + "connection": "keep-alive", + "x-cache": "cp1064 hit (14), cp3010 hit (60), cp3005 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/scheme/scheme.png b/fedcode/static/pictogram-gh-pages/scheme/scheme.png new file mode 100644 index 0000000..d298988 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/scheme/scheme.png differ diff --git a/fedcode/static/pictogram-gh-pages/shards/shards.json b/fedcode/static/pictogram-gh-pages/shards/shards.json new file mode 100644 index 0000000..ec7bf3e --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/shards/shards.json @@ -0,0 +1,33 @@ +{ + "name": "shards", + "source": { + "url": "https://avatars0.githubusercontent.com/u/6539796?v=3&s=200", + "referrer": "https://github.com/crystal-lang", + "headers": { + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "etag": "\"385531d498d8d3083523aa2eb9510d4160fc3f47\"", + "last-modified": "Fri, 28 Aug 2015 20:04:02 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-xss-protection": "1; mode=block", + "x-github-request-id": "B91F131F:56A6:42E13E2:56D4CA70", + "content-length": "5510", + "accept-ranges": "bytes", + "date": "Tue, 01 Mar 2016 09:33:46 GMT", + "via": "1.1 varnish", + "connection": "close", + "x-served-by": "cache-lhr6322-LHR", + "x-cache": "HIT", + "x-cache-hits": "2", + "access-control-allow-origin": "*", + "x-fastly-request-id": "432c66ef4c48ad83550c08460e7014413570c519", + "expires": "Tue, 01 Mar 2016 09:38:46 GMT", + "source-age": "38794", + "vary": "Authorization,Accept-Encoding" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/shards/shards.png b/fedcode/static/pictogram-gh-pages/shards/shards.png new file mode 100644 index 0000000..9d9cc02 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/shards/shards.png differ diff --git a/fedcode/static/pictogram-gh-pages/sublime/sublime.json b/fedcode/static/pictogram-gh-pages/sublime/sublime.json new file mode 100644 index 0000000..898e618 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/sublime/sublime.json @@ -0,0 +1,26 @@ +{ + "name": "sublime", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/en/4/4c/Sublime_Text_Logo.png", + "referrer": "http://en.wikipedia.org/wiki/File:Sublime_Text_Logo.png", + "headers": { + "x-object-meta-sha1base36": "hv36qmmssteu7h0ukpm2uccspz5zryx", + "last-modified": "Thu, 03 Oct 2013 23:05:16 GMT", + "etag": "8a483f7a7efcf995491cb6d6a6474010", + "x-timestamp": "1380841515.42109", + "content-type": "image/png", + "x-trans-id": "txcfd34f52c6e646a1b81c0-005506ed92", + "x-varnish": "2645010696 2614188073, 1824459470 1793825958, 3545802880", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "31566", + "accept-ranges": "bytes", + "date": "Mon, 16 Mar 2015 23:48:14 GMT", + "age": "32299", + "connection": "keep-alive", + "x-cache": "cp1048 hit (91), cp3017 hit (24), cp3018 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/sublime/sublime.png b/fedcode/static/pictogram-gh-pages/sublime/sublime.png new file mode 100644 index 0000000..74ce673 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/sublime/sublime.png differ diff --git a/fedcode/static/pictogram-gh-pages/swift/swift.json b/fedcode/static/pictogram-gh-pages/swift/swift.json new file mode 100644 index 0000000..9e25a39 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/swift/swift.json @@ -0,0 +1,26 @@ +{ + "name": "swift", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/en/4/43/Apple_Swift_Logo.png", + "referrer": "http://en.wikipedia.org/wiki/File:Apple_Swift_Logo.png", + "headers": { + "x-object-meta-sha1base36": "2ptisrx1l054z84wesbuph4ksw8jxac", + "last-modified": "Mon, 02 Jun 2014 19:58:39 GMT", + "etag": "7aa4103a8f6eb0040d3c2d665987c864", + "x-timestamp": "1401739118.51794", + "content-type": "image/png", + "x-trans-id": "tx7163bad1fc1c4552b58b2-0055097825", + "x-varnish": "1445163199, 2769866930 2768810317, 2260152190", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish", + "content-length": "26325", + "accept-ranges": "bytes", + "date": "Wed, 18 Mar 2015 13:15:38 GMT", + "age": "597", + "connection": "keep-alive", + "x-cache": "cp1050 miss (0), cp3008 hit (1), cp3009 frontend miss (0)", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/swift/swift.png b/fedcode/static/pictogram-gh-pages/swift/swift.png new file mode 100644 index 0000000..baf5e3b Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/swift/swift.png differ diff --git a/fedcode/static/pictogram-gh-pages/tex/tex.json b/fedcode/static/pictogram-gh-pages/tex/tex.json new file mode 100644 index 0000000..8cfc644 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/tex/tex.json @@ -0,0 +1,28 @@ +{ + "name": "tex", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/6/68/TeX_logo.svg/200px-TeX_logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:TeX_logo.svg", + "headers": { + "x-object-meta-sha1base36": "qp6w2uvrsdvwrva95lt8iinuxo6zifz", + "content-disposition": "inline;filename*=UTF-8''TeX_logo.svg.png", + "last-modified": "Sun, 02 Mar 2014 07:48:08 GMT", + "etag": "fdb248fa6053759fd85453b9e04ce6f9", + "x-timestamp": "1393746487.81891", + "content-type": "image/png", + "x-trans-id": "tx760ce7dca40c4a83b38a9-00550bfbcf", + "x-varnish": "1807553663 1764028894, 1606043310 1466343979, 2471478251 2471362502", + "content-length": "3739", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 20:18:58 GMT", + "age": "120420", + "x-cache": "cp1050 hit (12), cp3006 hit (39), cp3010 frontend hit (1), MISS from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/tex/tex.orig.png b/fedcode/static/pictogram-gh-pages/tex/tex.orig.png new file mode 100644 index 0000000..213f2e9 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/tex/tex.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/tex/tex.png b/fedcode/static/pictogram-gh-pages/tex/tex.png new file mode 100644 index 0000000..4f876a8 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/tex/tex.png differ diff --git a/fedcode/static/pictogram-gh-pages/typescript/typescript.json b/fedcode/static/pictogram-gh-pages/typescript/typescript.json new file mode 100644 index 0000000..c3652d3 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/typescript/typescript.json @@ -0,0 +1,27 @@ +{ + "name": "typescript", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/a/a6/TypeScript_Logo.png", + "referrer": "http://commons.wikimedia.org/wiki/File:TypeScript_Logo.png", + "headers": { + "x-object-meta-sha1base36": "ta8zk9e0sbxw3dgndt2gf5az2lm2550", + "last-modified": "Fri, 08 Aug 2014 13:37:25 GMT", + "etag": "bd3114606fdd1882d29146523420bcaf", + "x-timestamp": "1407505044.06077", + "content-type": "image/png", + "x-trans-id": "tx9a3ac9c48dc64eea9e35b-00550d72c5", + "x-varnish": "2120026215 2105357961, 3309311353 3276531616, 2561116907", + "content-length": "3617", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 19:52:00 GMT", + "age": "22810", + "x-cache": "cp1063 hit (13), cp3007 hit (18), cp3005 frontend miss (0), MISS from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/typescript/typescript.orig.png b/fedcode/static/pictogram-gh-pages/typescript/typescript.orig.png new file mode 100644 index 0000000..442bcf4 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/typescript/typescript.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/typescript/typescript.png b/fedcode/static/pictogram-gh-pages/typescript/typescript.png new file mode 100644 index 0000000..5590f1b Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/typescript/typescript.png differ diff --git a/fedcode/static/pictogram-gh-pages/wordpress/wordpress.json b/fedcode/static/pictogram-gh-pages/wordpress/wordpress.json new file mode 100644 index 0000000..27f0966 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/wordpress/wordpress.json @@ -0,0 +1,34 @@ +{ + "name": "wordpress", + "source": { + "url": "https://avatars0.githubusercontent.com/u/276006?v=3&s=200", + "referrer": "https://github.com/wordpress", + "headers": { + "date": "Sun, 15 Mar 2015 10:33:53 GMT", + "server": "Apache", + "access-control-allow-origin": "*", + "cache-control": "max-age=300", + "content-security-policy": "default-src 'none'", + "content-type": "image/png", + "last-modified": "Thu, 01 Dec 2011 07:14:42 GMT", + "strict-transport-security": "max-age=31557600", + "timing-allow-origin": "https://github.com", + "x-content-type-options": "nosniff", + "x-frame-options": "deny", + "x-github-request-id": "c698b2f7-cafe-11e4-8e2f-f7d30ac9dc72", + "x-xss-protection": "1; mode=block", + "host": "avatars.githubusercontent.com", + "content-length": "32964", + "accept-ranges": "bytes", + "via": "1.1 varnish", + "x-served-by": "cache-lhr6323-LHR", + "x-cache": "MISS", + "x-cache-hits": "0", + "expires": "Sun, 15 Mar 2015 10:38:53 GMT", + "source-age": "0", + "vary": "AuthorizationAccept-Encoding", + "keep-alive": "timeout=10, max=50", + "connection": "Keep-Alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/wordpress/wordpress.png b/fedcode/static/pictogram-gh-pages/wordpress/wordpress.png new file mode 100644 index 0000000..fb73630 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/wordpress/wordpress.png differ diff --git a/fedcode/static/pictogram-gh-pages/xml/xml.json b/fedcode/static/pictogram-gh-pages/xml/xml.json new file mode 100644 index 0000000..efa8457 --- /dev/null +++ b/fedcode/static/pictogram-gh-pages/xml/xml.json @@ -0,0 +1,26 @@ +{ + "name": "xml", + "source": { + "url": "http://upload.wikimedia.org/wikipedia/commons/thumb/9/9d/Xml_logo.svg/200px-Xml_logo.svg.png", + "referrer": "http://commons.wikimedia.org/wiki/File:Xml_logo.svg", + "headers": { + "last-modified": "Sat, 02 Nov 2013 00:40:48 GMT", + "etag": "99291c0f454283fa81ddd4702d118024", + "x-timestamp": "1383352847.07070", + "content-type": "image/png", + "x-trans-id": "txdf2a4bc6c4c84b5db58df-00550dd009", + "x-varnish": "3532675300, 2957205573 2957142125, 264810498", + "content-length": "3048", + "accept-ranges": "bytes", + "date": "Sat, 21 Mar 2015 20:10:15 GMT", + "age": "29", + "x-cache": "cp1051 miss (0), cp3010 hit (1), cp3018 frontend miss (0), MISS from cache_server", + "access-control-allow-origin": "*", + "access-control-expose-headers": "Age, Date, Content-Length, Content-Range, X-Content-Duration, X-Cache, X-Varnish", + "timing-allow-origin": "*", + "x-cache-lookup": "MISS from cache_server:3128", + "via": "1.1 varnish, 1.1 varnish, 1.1 varnish, 1.0 cache_server:3128 (squid/2.6.STABLE21)", + "connection": "keep-alive" + } + } +} \ No newline at end of file diff --git a/fedcode/static/pictogram-gh-pages/xml/xml.orig.png b/fedcode/static/pictogram-gh-pages/xml/xml.orig.png new file mode 100644 index 0000000..64a3848 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/xml/xml.orig.png differ diff --git a/fedcode/static/pictogram-gh-pages/xml/xml.png b/fedcode/static/pictogram-gh-pages/xml/xml.png new file mode 100644 index 0000000..14142b2 Binary files /dev/null and b/fedcode/static/pictogram-gh-pages/xml/xml.png differ diff --git a/fedcode/templates/base.html b/fedcode/templates/base.html new file mode 100644 index 0000000..6f744ab --- /dev/null +++ b/fedcode/templates/base.html @@ -0,0 +1,31 @@ +{% load static %} + + + + + + + {% block title %}FederatedCode.io{% endblock %} + + + + + + + + + {% block json_ld_script %} + {% endblock %} + + {% block extra-head %}{% endblock %} + + + + {% include "navbar.html" %} + {% include "messages.html" %} + {% block content %} + {% endblock %} + {% include "footer.html" %} + + + \ No newline at end of file diff --git a/fedcode/templates/create_repository.html b/fedcode/templates/create_repository.html new file mode 100644 index 0000000..501fc8f --- /dev/null +++ b/fedcode/templates/create_repository.html @@ -0,0 +1,31 @@ +{% extends "base.html" %} +{% block title %} +Sign up page +{% endblock %} + +{% block content %} +
+
+
+ {% if form.errors %} +
+
+

Error

+
+
+ {{ form.errors }} +
+
+{% endif %} +

Create Git Repository

+
+ {% csrf_token %} + {{ form.as_p }} + +
+
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/create_review.html b/fedcode/templates/create_review.html new file mode 100644 index 0000000..5a6f180 --- /dev/null +++ b/fedcode/templates/create_review.html @@ -0,0 +1,119 @@ +{% extends "base.html" %} +{% block title %} +Create Review +{% endblock %} + +{% block extra-head %} + +{% endblock %} +{% block content %} + +
+
+ {% if messages %} + {% for message in messages %} +
+
+ {{ message }} +
+
+ {% endfor %} + {% endif %} +
+
+ +
+
+

Choose a File

+
+ +
+ {% csrf_token %} + {{ fetch_form }} +
+ +
+
+ +
+
+
+ {% csrf_token %} +
+
+ + +
+
+
+ +
+
+
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/footer.html b/fedcode/templates/footer.html new file mode 100644 index 0000000..949c6ec --- /dev/null +++ b/fedcode/templates/footer.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/fedcode/templates/home.html b/fedcode/templates/home.html new file mode 100644 index 0000000..60de0c0 --- /dev/null +++ b/fedcode/templates/home.html @@ -0,0 +1,72 @@ +{% extends "base.html" %} +{% load static %} +{% load webfinger_image %} +{% block title %} +Home +{% endblock %} + +{% block extra-head %} + +{% endblock %} +{% block content %} +
+
+
+
+ +
+

Home

+
+
+ {% for note in page_note %} +
+
+

+ purl-image +

+
+
+ + + +

{{ note.reputation_value }}

+ + + +
+ +
+
+ {{ note.acct }} +
+
{{ note.content }}
+
+ +
+
+
+ last update: {{ note.updated_at }} +
+
+ {% endfor %} + +
+
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/login.html b/fedcode/templates/login.html new file mode 100644 index 0000000..19b8b58 --- /dev/null +++ b/fedcode/templates/login.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} +{% block title %} +Login page +{% endblock %} + +{% block content %} + +
+
+
+ {% if form.errors %} +
+
+
+
+

Your username and password didn't match. Please try again.

+
+
+
+
+ {% endif %} +
+ {% csrf_token %} + +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/messages.html b/fedcode/templates/messages.html new file mode 100644 index 0000000..d3c7722 --- /dev/null +++ b/fedcode/templates/messages.html @@ -0,0 +1,13 @@ +
+
+ {% if messages %} + {% for message in messages %} +
+
+ {{ message }} +
+
+ {% endfor %} + {% endif %} +
+
\ No newline at end of file diff --git a/fedcode/templates/navbar.html b/fedcode/templates/navbar.html new file mode 100644 index 0000000..307d6ce --- /dev/null +++ b/fedcode/templates/navbar.html @@ -0,0 +1,80 @@ + \ No newline at end of file diff --git a/fedcode/templates/note.html b/fedcode/templates/note.html new file mode 100644 index 0000000..f6124a9 --- /dev/null +++ b/fedcode/templates/note.html @@ -0,0 +1,90 @@ +{% extends "base.html" %} +{% load static %} +{% load webfinger_image %} +{% block title %} +Note page +{% endblock %} +{% block extra-head %} + +{% endblock %} +{% block content %} +
+
+
+
+ +
+
+

+ purl-image +

+
+
+ + + +

{{ note.reputation_value }}

+ + + +
+ +
+
+

+ {{ note.acct }} +
+

{{ note.content }}
+

+
+
+ +
+ last update: {{ note.updated_at }} +
+
+ + {% for note_r in note.replies.all %} +
+
+
+

+ @{{ note_r.acct }} +

{{ note_r.content }}

+

+
+
+
+ last update: {{ note.updated_at }} +
+
+ {% endfor %} + +
+ +
+

+ +

+
+
+
+
+

+ {% csrf_token %} + {{ form }} +

+
+
+

+ +

+
+
+
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/pkg_list.html b/fedcode/templates/pkg_list.html new file mode 100644 index 0000000..3c711cd --- /dev/null +++ b/fedcode/templates/pkg_list.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} +{% block title %} +Purl List +{% endblock %} + +{% block extra-head %} +{% endblock %} +{% block content %} +
+
+
+ +
+
+

Package List

+
+
+
+ {{ form }} + +
+ {% for package in package_list %} +
+
+

Number of Followers

+

{{ package.followers_count }}

+
+
+
+

{{ package.purl }}

+ Created by @{{ package.service.user.username }} +
+
+
+
+ {% endfor %} + {% if is_paginated %} + + {% endif %} +
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/pkg_profile.html b/fedcode/templates/pkg_profile.html new file mode 100644 index 0000000..36759b6 --- /dev/null +++ b/fedcode/templates/pkg_profile.html @@ -0,0 +1,115 @@ +{% extends "base.html" %} +{% load webfinger_image %} +{% block title %} +Your Profile +{% endblock %} +{% block json_ld_script %} + +{% endblock %} +{% block content %} +
+
+

+ @{{ package.purl }} +

+ +
+

+ purl-image +

+
+ + + +

+ {{ package.note }} +

+ +
+ {% if user.is_authenticated %} +
+ {% csrf_token %} + {% if not is_user_follow and not user.service %} + + {% endif %} + + {% if is_user_follow and not user.service %} + + {% endif %} +
+ {% endif %} + +
+ {% if user.is_anonymous %} +
+ {% csrf_token %} + {{ subscribe_form }} + +
+ {% endif %} + + {% if user.service %} +
+ {% csrf_token %} + {{ note_form }} + +
+ {% endif %} + +
+
+
+
+ +
+
+
+

+ Posts +

+
+
+
+ {% for post_note in purl_notes %} +
+ @{{ post_note.acct }} , updated_at {{ post_note.updated_at }} +
+
{{ post_note.content }}
+
+
+ {% endfor %} +
+
+
+
+
+
+
+{% endblock %} diff --git a/fedcode/templates/repo_list.html b/fedcode/templates/repo_list.html new file mode 100644 index 0000000..a7edfa1 --- /dev/null +++ b/fedcode/templates/repo_list.html @@ -0,0 +1,57 @@ +{% extends "base.html" %} +{% block title %} +Git Repository List +{% endblock %} + +{% block extra-head %} +{% endblock %} +{% block content %} +
+
+
+
+ +
+

Git Repository List

+
+
+ +
+ {{ form }} + +
+ + {% for repo in repo_list %} +
+
+

Number of Reviews

+

{{ repo.review_count }}

+
+
+
+

{{ repo.url }}

+ @{{ repo.admin.user.username }} + {% if user.person %} + Create Review + {% endif %} + {% if user.service %} +
+ {% csrf_token %} + +
+ {% endif %} + +
+ +
+
+ {% endfor %} + +
+ +
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/review.html b/fedcode/templates/review.html new file mode 100644 index 0000000..61dba45 --- /dev/null +++ b/fedcode/templates/review.html @@ -0,0 +1,122 @@ +{% extends "base.html" %} +{% load static %} +{% block title %} +Review page +{% endblock %} + +{% block extra-head %} + + +{% endblock %} +{% block content %} +

+ {{ review.headline }} + {% if review.status == 0 %} + 🟢 Open + {% elif review.status == 1 %} + ⚪ Draft + {% elif review.status == 2 %} + 🔴 Closed + {% elif review.status == 3 %} + 🔵 Merged + {% endif %} + +

+
+
+
+
+
+ {{ patch|safe }} +
+ +
+
+ + +
+
+

Votes

+

{{ review.reputation_value }}

+
+
+ + +
+ +
+
+ {% for note in review.notes.all %} +
+
+ + + +

{{ note.reputation_value }}

+ + + +
+
+
+

+ {{ note.username }} + @{{ note.acct }} + updated_at: {{ note.updated_at }} +
+ {{ note.content }} +

+
+
+
+ {% endfor %} +
+ {% csrf_token %} +
+

+ +

+
+
+
+ {{ comment_form.as_p }} +
+ +
+
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/review_list.html b/fedcode/templates/review_list.html new file mode 100644 index 0000000..7121ea6 --- /dev/null +++ b/fedcode/templates/review_list.html @@ -0,0 +1,45 @@ +{% extends "base.html" %} +{% block title %} +Review List +{% endblock %} + +{% block extra-head %} +{% endblock %} +{% block content %} +
+
+
+
+ +
+

Review List

+
+
+
+ {{ form }} + +
+ {% for review in review_list %} +
+
+

Votes

+

{{ review.reputation_value }}

+
+
+
+

{{ review.headline }}

+ @{{ review.author.user.username }} + updated_at : {{ review.updated_at }} +
+
+
+
+ {% endfor %} +
+ +
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/update_profile.html b/fedcode/templates/update_profile.html new file mode 100644 index 0000000..7a3be77 --- /dev/null +++ b/fedcode/templates/update_profile.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} +{% block title %} +Update Profile +{% endblock %} + +{% block content %} +
+
+
+
+ +
+

@{{ person.user.username }}

+
+ {% csrf_token %} +
+
{{ form.as_p }}
+ +
+ +
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/user_profile.html b/fedcode/templates/user_profile.html new file mode 100644 index 0000000..8a8825f --- /dev/null +++ b/fedcode/templates/user_profile.html @@ -0,0 +1,74 @@ +{% extends "base.html" %} +{% block title %} +Your Profile +{% endblock %} + +{% block json_ld_script %} + +{% endblock %} + +{% block content %} +
+
+
+ +
+

+ @{{ person.user.username }} +

+ + +

{{ person.summary }}

+

+ +

+ +
+
+
+ + +
+
+
+{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/user_sign_up.html b/fedcode/templates/user_sign_up.html new file mode 100644 index 0000000..da368b0 --- /dev/null +++ b/fedcode/templates/user_sign_up.html @@ -0,0 +1,58 @@ +{% extends "base.html" %} +{% block title %} +Sign up page +{% endblock %} + +{% block content %} +
+
+
+ {% if form.errors %} +
+
+

Error

+
+
+ {{ form.errors }} +
+
+{% endif %} + +

Sign up Form

+
+ {% csrf_token %} +
+ +
+ + Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only. +
+
+
+ +
+ +
+
+
+ +
+ +
  • Your password can’t be too similar to your other personal information.
  • Your password must contain at least 8 characters.
  • Your password can’t be a commonly used password.
  • Your password can’t be entirely numeric.
+ +
+
+
+ +
+ +
+
+ +
+
+ +
+
+ +{% endblock %} \ No newline at end of file diff --git a/fedcode/templates/webfinger_package.json b/fedcode/templates/webfinger_package.json new file mode 100644 index 0000000..c93cbf3 --- /dev/null +++ b/fedcode/templates/webfinger_package.json @@ -0,0 +1,15 @@ +{ + "subject": "{{ resource }}", + "links": [ + { + "rel": "https://webfinger.net/rel/profile-page", + "type": "text/html", + "href": "https://{{ domain }}/purls/@{{ purl_string }}" + }, + { + "rel": "self", + "type": "application/activity+json", + "href": "https://{{ domain }}/api/v0/purls/@{{ purl_string }}" + } + ] +} diff --git a/fedcode/templates/webfinger_user.json b/fedcode/templates/webfinger_user.json new file mode 100644 index 0000000..4b5d4e0 --- /dev/null +++ b/fedcode/templates/webfinger_user.json @@ -0,0 +1,15 @@ +{ + "subject": "{{ resource }}", + "links": [ + { + "rel": "https://webfinger.net/rel/profile-page", + "type": "text/html", + "href": "https://{{ domain }}/users/@{{ username }}" + }, + { + "rel": "self", + "type": "application/activity+json", + "href": "https://{{ domain }}/api/v0/users/@{{ username }}" + } + ] +} diff --git a/fedcode/templatetags/__init__.py b/fedcode/templatetags/__init__.py new file mode 100644 index 0000000..bdac1cd --- /dev/null +++ b/fedcode/templatetags/__init__.py @@ -0,0 +1,8 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# diff --git a/fedcode/templatetags/webfinger_image.py b/fedcode/templatetags/webfinger_image.py new file mode 100644 index 0000000..1327ea1 --- /dev/null +++ b/fedcode/templatetags/webfinger_image.py @@ -0,0 +1,27 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +from django import template +from packageurl import PackageURL + +from federatedcode.settings import STATIC_URL + +register = template.Library() + + +@register.filter +def get_pkg_image(purl_webfinger): + """ + Return the path of the image package + """ + try: + purl, _ = purl_webfinger.split("@") + package_type = PackageURL.from_string(purl).type + return "/" + STATIC_URL + "pictogram-gh-pages/" + package_type + "/" + package_type + ".png" + except ValueError: + return "" diff --git a/fedcode/utils.py b/fedcode/utils.py new file mode 100644 index 0000000..b6751f8 --- /dev/null +++ b/fedcode/utils.py @@ -0,0 +1,143 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +import io +import json +import os +from urllib.parse import urlparse + +import requests +from django.urls import resolve +from django.urls import reverse +from git.repo.base import Repo +from packageurl import PackageURL +from federatedcode.settings import FEDERATED_CODE_DOMAIN + + +def parse_webfinger(subject): + """ + get the username and host from webfinger acct:user@host + >>> parse_webfinger("acct:ziadhany@example.com") + ('ziadhany', 'example.com') + >>> parse_webfinger("acct:") + ('', '') + >>> parse_webfinger("ziadhany@example.com") + ('ziadhany', 'example.com') + """ + if subject.startswith("acct"): + acct = subject[5:] + result = acct.split("@") + user_part, host = "", "" + if len(result) == 2: + user_part, host = result + return user_part, host + else: + return tuple(subject.split("@")) + + +def generate_webfinger(username, domain=FEDERATED_CODE_DOMAIN): + return username + "@" + domain + + +def clone_git_repo(repo_path, repo_url): + """ + Clone Git repository in ${repo_path}/repo_name.git + """ + repo_name = str(hash(repo_url)) + abspath = os.path.join(repo_path, repo_name) + repo = Repo.clone_from(repo_url, str(abspath)) + return repo + + +def full_reverse(page_name, *args, **kwargs): + web_page = reverse(page_name, args=args, kwargs=kwargs) + return f'{"https://"}{FEDERATED_CODE_DOMAIN}{web_page}' + + +def full_resolve(full_path): + parser = urlparse(full_path) + resolver = resolve(parser.path) + return resolver.kwargs, resolver.url_name + + +def check_purl_actor(purl_string): + """ + Purl actor is a purl without a version + """ + purl = PackageURL.from_string(purl_string) + if not (purl.version or purl.qualifiers or purl.subpath): + return True + return False + + +def ap_collection(objects): + """ + accept the result of the query like filter and Add all objects in activitypub collection format + https://www.w3.org/TR/activitystreams-vocabulary/#dfn-orderedcollection + """ + return { + "type": "OrderedCollection", + "totalItems": objects.count(), + "orderedItems": [obj.to_ap for obj in objects.all()], + } + + +def webfinger_actor(domain, user): + """""" + acct = generate_webfinger(user, domain) + url = f"http://{domain}/.well-known/webfinger?resource=acct:{acct}" # TODO http -> https + headers = {"User-Agent": ""} # TODO + try: + response = requests.get(url, headers=headers) + if response.status_code == 200: + return response.json()["links"][1][ + "href" + ] # TODO please check if type = "application/activity+json" + except requests.exceptions.RequestException as e: + return f"Failed to fetch the actor {e}" + + +def fetch_actor(url): + """ + fetch actor profile URL and return profile Json-LD + """ + headers = {"User-Agent": ""} # TODO + try: + response = requests.get(url, headers=headers) + if response.status_code == 200: + return response.json() + + except requests.exceptions.HTTPError as e: + return f"Http Error: {e}" + except requests.exceptions.ConnectionError as e: + return f"Error Connecting: {e}" + except requests.exceptions.Timeout as e: + return f"Timeout Error:{e}" + except requests.exceptions.RequestException as e: + return f"OOps: Something Else {e}" + + return "Failed to fetch the actor" + + +def file_data(file_name): + with open(file_name) as file: + data = file.read() + return json.loads(data) + + +def load_git_file(git_repo_obj, filename, commit_id): + """ + Get file data from a specific git commit using gitpython + copied from https://stackoverflow.com/a/54900961/9871531 + """ + commit = git_repo_obj.commit(commit_id) + target_file = commit.tree / filename + + with io.BytesIO(target_file.data_stream.read()) as f: + return f.read().decode("utf-8") diff --git a/fedcode/views.py b/fedcode/views.py new file mode 100644 index 0000000..96fb247 --- /dev/null +++ b/fedcode/views.py @@ -0,0 +1,842 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import difflib +import json +import logging +import os.path + +import requests +from django.contrib.auth import login +from django.contrib.auth.decorators import login_required +from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.auth.models import User +from django.contrib.auth.views import LoginView +from django.core.paginator import Paginator +from django.http import Http404 +from django.http import HttpResponse +from django.http import HttpResponseBadRequest +from django.http import HttpResponseForbidden +from django.http import JsonResponse +from django.shortcuts import get_object_or_404 +from django.shortcuts import redirect +from django.shortcuts import render +from django.urls import reverse_lazy +from django.utils.decorators import method_decorator +from django.views import View +from django.views.decorators.csrf import csrf_exempt +from django.views.decorators.http import require_http_methods +from django.views.generic import CreateView +from django.views.generic import DetailView +from django.views.generic import FormView +from django.views.generic import ListView +from django.views.generic import TemplateView +from django.views.generic.edit import FormMixin +from django.views.generic.edit import UpdateView + +from fedcode.forms import FetchForm +from fedcode.forms import PersonSignUpForm +from fedcode.forms import SearchPackageForm +from fedcode.forms import SearchRepositoryForm +from fedcode.forms import SearchReviewForm +from fedcode.forms import SubscribePackageForm +from federatedcode.settings import AP_CONTENT_TYPE, FEDERATED_CODE_GIT_PATH +from federatedcode.settings import FEDERATED_CODE_DOMAIN +from federatedcode.settings import env + +from .activitypub import AP_CONTEXT +from .activitypub import create_activity_obj +from .activitypub import has_valid_header +from .forms import CreateGitRepoForm +from .forms import CreateNoteForm +from .forms import CreateReviewForm +from .forms import ReviewStatusForm +from .models import Follow, SyncRequest +from .models import Note +from .models import Person +from .models import Package +from .models import Repository +from .models import Reputation +from .models import Review +from .models import Vulnerability +from .signatures import HttpSignature,FEDERATED_CODE_PUBLIC_KEY +from .utils import ap_collection +from .utils import full_reverse +from .utils import generate_webfinger +from .utils import load_git_file +from .utils import parse_webfinger +from .utils import webfinger_actor +from django.contrib.auth.models import auth +from django.contrib import messages +from django.contrib.contenttypes.models import ContentType + +logger = logging.getLogger(__name__) + +FEDERATED_CODE_CLIENT_ID = env.str("FEDERATED_CODE_CLIENT_ID") +FEDERATED_CODE_CLIENT_SECRET = env.str("FEDERATED_CODE_CLIENT_SECRET") + + +def logout(request): + auth.logout(request) + return redirect("login") + + +class WebfingerView(View): + def get(self, request): + """/.well-known/webfinger?resource=acct:gargron@mastodon.social""" + resource = request.GET.get("resource") + + if not resource: + return HttpResponseBadRequest("No resource found") + + obj, domain = parse_webfinger(resource) + + if FEDERATED_CODE_DOMAIN != domain or not obj: + return HttpResponseBadRequest("Invalid domain") + + if obj.startswith("pkg:"): + try: + package = Package.objects.get(purl=obj) + except Package.DoesNotExist: + return HttpResponseBadRequest("Not an Purl resource") + + return render( + request, + "webfinger_package.json", + status=200, + content_type="application/jrd+json", + context={ + "resource": resource, + "domain": FEDERATED_CODE_DOMAIN, + "purl_string": package.purl, + }, + ) + else: + try: + user = User.objects.get(username=obj) + except User.DoesNotExist: + return HttpResponseBadRequest("Not an account resource") + + return render( + request, + "webfinger_user.json", + status=200, + content_type="application/jrd+json", + context={ + "resource": resource, + "domain": FEDERATED_CODE_DOMAIN, + "username": user.username, + }, + ) + + +class HomeView(View): + def get(self, request, *args, **kwargs): + if hasattr(self.request.user, "person"): + packages = [ + generate_webfinger(follow.package.purl) + for follow in Follow.objects.filter(person=self.request.user.person) + ] + note_list = Note.objects.filter(acct__in=packages).order_by("updated_at__minute") + paginator = Paginator(note_list, 10) + page_number = request.GET.get("page") + page_note = paginator.get_page(page_number) + return render(request, "home.html", context={"page_note": page_note}) + elif hasattr(self.request.user, "service"): + return redirect("repo-list") + else: + return redirect("login") + + +class PersonView(DetailView): + model = Person + template_name = "user_profile.html" + slug_field = "user__username" + context_object_name = "person" + + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(**kwargs) + following_list = Follow.objects.filter(person=self.object) + paginator = Paginator(following_list, 10) + page_number = self.request.GET.get("page") + context["followings"] = paginator.get_page(page_number) + context["follow_count"] = following_list.count() + return context + + +class PackageView(DetailView, FormMixin): + model = Package + template_name = "pkg_profile.html" + slug_field = "purl" + context_object_name = "package" + form_class = CreateNoteForm + + def get_success_url(self): + return self.request.path + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + # slug = purl_string + + context["purl_notes"] = Note.objects.filter(acct=generate_webfinger(self.kwargs["slug"])) + + context["followers"] = Follow.objects.filter(package=self.object) + + if self.request.user.is_authenticated: + context["is_user_follow"] = ( + True + if Follow.objects.filter(package=self.object, person__user=self.request.user).first() + else False + ) + + context["note_form"] = CreateNoteForm() + context["subscribe_form"] = SubscribePackageForm() + return context + + def post(self, request, *args, **kwargs): + self.object = self.get_object() + note_form = self.get_form() + if note_form.is_valid(): + note_form.instance.acct = generate_webfinger(self.kwargs["slug"]) + note_form.instance.note_type = 0 + note_form.save() + return super(PackageView, self).form_valid(note_form) + else: + return self.form_invalid(note_form) + + +def is_service_user(view): + def wrapper(request, *args, **kwargs): + if hasattr(request.user, "service"): + return view(request, *args, **kwargs) + else: + return HttpResponseForbidden() + + return wrapper + + +@method_decorator(is_service_user, name="dispatch") +class CreatGitView(LoginRequiredMixin, CreateView): + model = Repository + form_class = CreateGitRepoForm + template_name = "create_repository.html" + success_url = reverse_lazy("repo-list") + + def form_valid(self, form): + self.object = form.save(commit=False) + self.object.admin = self.request.user.service + try: + self.object.save() + messages.success(self.request, "Git repo successfully created") + except Exception as e: # + logger.error(f"Error occurred while creating git repo {e}") + messages.error(self.request, "An error occurred") + + return super(CreatGitView, self).form_valid(form) + + +@method_decorator(is_service_user, name="dispatch") +class CreateSync(LoginRequiredMixin, View): + def post(self, request, repository_id): + try: + repo = Repository.objects.get(id=repository_id) + if repo.admin == self.request.user.service: + SyncRequest.objects.create(repo=repo) + messages.success(self.request, "The sync request was sent successfully") + else: + return HttpResponseForbidden("Invalid Git Repository Admin") + except Repository.DoesNotExist: + return HttpResponseBadRequest("Invalid Git Repository") + return redirect("repo-list") + + +class UserLogin(LoginView): + template_name = "login.html" + next_page = "/review-list" + + +class PersonSignUp(FormView): + form_class = PersonSignUpForm + success_url = "/review-list" + template_name = "user_sign_up.html" + + def form_valid(self, form): + user = form.save() + if user: + person = Person.objects.create(user=user) + person.save() + login(self.request, user, backend="django.contrib.auth.backends.ModelBackend") + return super(PersonSignUp, self).form_valid(form) + + +class RepositoryListView(ListView, FormMixin): + model = Repository + context_object_name = "repo_list" + template_name = "repo_list.html" + paginate_by = 10 + form_class = SearchRepositoryForm + + def get_queryset(self): + form = self.form_class(self.request.GET) + if form.is_valid(): + return Repository.objects.filter(url__icontains=form.cleaned_data.get("search")) + return Repository.objects.all() + + +class ReviewListView(ListView, FormMixin): + model = Review + context_object_name = "review_list" + template_name = "review_list.html" + paginate_by = 10 + form_class = SearchReviewForm + + def get_queryset(self): + form = self.form_class(self.request.GET) + if form.is_valid(): + return Review.objects.filter(headline__icontains=form.cleaned_data.get("search")) + return Review.objects.all() + + +class PackageListView(ListView, FormMixin): + model = Package + context_object_name = "package_list" + template_name = "pkg_list.html" + paginate_by = 20 + form_class = SearchPackageForm + + def get_queryset(self): + form = self.form_class(self.request.GET) + if form.is_valid(): + return Package.objects.filter(purl__icontains=form.cleaned_data.get("search")) + return Package.objects.all() + + +class ReviewView(LoginRequiredMixin, TemplateView): + template_name = "review.html" + + def get_context_data(self, request, **kwargs): + context = super().get_context_data(**kwargs) + context["review"] = get_object_or_404(Review, id=self.kwargs["review_id"]) + vul_source = context["review"].data.splitlines() + vul_target = load_git_file( + git_repo_obj=context["review"].repository.git_repo_obj, + filename=context["review"].filepath, + commit_id=context["review"].commit, + ).splitlines() + d = difflib.HtmlDiff() + context["patch"] = d.make_table( + vul_source, vul_target, fromdesc="original", todesc="modified" + ) + return context + + def get(self, request, *args, **kwargs): + context = self.get_context_data(request, **kwargs) + return render( + request, + self.template_name, + { + "status_form": ReviewStatusForm(), + "comment_form": CreateNoteForm(), + **context, + }, + ) + + def post(self, request, *args, **kwargs): + context = self.get_context_data(request, **kwargs) + status_form = ReviewStatusForm(request.POST, instance=context["review"]) + comment_form = CreateNoteForm(request.POST) + if status_form.is_bound and status_form.is_valid(): + status_form.save() + + elif comment_form.is_bound and comment_form.is_valid(): + comment_form.save(commit=False) + comment_form.instance.acct = generate_webfinger(request.user.username) + comment = comment_form.save() + context["review"].notes.add(comment) + context["review"].save() + + status_form = ReviewStatusForm() + comment_form = CreateNoteForm() + context = self.get_context_data(request, **kwargs) + return render( + request, + self.template_name, + {"status_form": status_form, "comment_form": comment_form, **context}, + ) + + +def fetch_repository_file(request, repository_id): + if request.headers.get("x-requested-with") == "XMLHttpRequest" and request.method == "POST": + request_body = json.load(request) + path = request_body.get("path") + + repo = get_object_or_404(Repository, id=repository_id).git_repo_obj + for entry in repo.commit().tree.traverse(): + if path == entry.path: + with open(entry.abspath) as f: + return JsonResponse({"filename": path, "text": f.read()}) + return HttpResponseBadRequest("Can't fetch this file") + + +@login_required +def obj_vote(request, obj_id, obj_type): + if request.headers.get("x-requested-with") == "XMLHttpRequest" and request.method == "PUT": + user_webfinger = generate_webfinger(request.user.username) + if obj_type == 'review': + obj = get_object_or_404(Review, id=obj_id) + elif obj_type == 'note': + obj = get_object_or_404(Note, id=obj_id) + else: + return HttpResponseBadRequest("Invalid object type to vote") + + request_body = json.load(request) + try: + content_type = ContentType.objects.get_for_model(Review if obj_type == 'review' else Note).id + rep_obj = Reputation.objects.get( + voter=user_webfinger, + object_id=obj.id, + content_type=content_type, + ) + if rep_obj: + vote_type = 'vote-down' if rep_obj.positive else 'vote-up' + rep_obj.delete() + return JsonResponse( + { + "message": "The vote has been removed successfully", + "vote-type": vote_type, + } + ) + except Reputation.DoesNotExist: + vote_type = request_body.get("vote-type") + rep_obj = None + if vote_type == "vote-up": + rep_obj = Reputation.objects.create( + voter=user_webfinger, + content_object=obj, + positive=True, + ) + elif vote_type == "vote-down": + rep_obj = Reputation.objects.create( + voter=user_webfinger, + content_object=obj, + positive=False, + ), + + else: + return HttpResponseBadRequest("Invalid vote-type request") + + if rep_obj: + return JsonResponse( + { + "message": "Voting completed successfully", + "vote-type": vote_type, + } + ) + return HttpResponseBadRequest("Invalid vote request") + + +class FollowPackageView(View): + def post(self, request, *args, **kwargs): + package = Package.objects.get(purl=self.kwargs["purl_string"]) + if request.user.is_authenticated: + if "follow" in request.POST: + follow_obj, _ = Follow.objects.get_or_create( + person=self.request.user.person, package=package + ) + + elif "unfollow" in request.POST: + try: + follow_obj = Follow.objects.get(person=self.request.user.person, package=package) + follow_obj.delete() + except Follow.DoesNotExist: + return HttpResponseBadRequest( + "Some thing went wrong when you try to unfollow this purl" + ) + elif request.user.is_anonymous: + form = SubscribePackageForm(request.POST) + if form.is_valid(): + user, domain = parse_webfinger(form.cleaned_data.get("acct")) + remote_actor_url = webfinger_actor(domain, user) + + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Follow", + "actor": { + "type": "Person", + "id": remote_actor_url, + }, + "object": { + "type": "Purl", + "id": package.absolute_url_ap, + }, + "to": [remote_actor_url], + } + ) + + activity = create_activity_obj(payload) + activity_response = activity.handler() + return JsonResponse( + { + "redirect_url": f"https://{domain}/authorize_interaction?uri={remote_actor_url}" + } + ) + else: + return HttpResponseBadRequest() + + return redirect(".") + + +class CreateReview(LoginRequiredMixin, TemplateView): + template_name = "create_review.html" + + def get_context_data(self, request, **kwargs): + context = super().get_context_data(**kwargs) + repo = Repository.objects.get(id=self.kwargs["repository_id"]) + context["git_files_tree"] = [ + entry.path + for entry in repo.git_repo_obj.commit().tree.traverse() + if entry.type == "blob" + ] + return context + + def get(self, request, *args, **kwargs): + context = self.get_context_data(request, **kwargs) + return render( + request, + self.template_name, + { + **context, + "create_review_form": CreateReviewForm(), + "fetch_form": FetchForm(), + }, + ) + + def post(self, request, *args, **kwargs): + create_review_form = CreateReviewForm(request.POST) + if create_review_form.is_valid() and request.user.person: + repo = Repository.objects.get(id=self.kwargs["repository_id"]) + commit = repo.git_repo_obj.head.commit + review = Review.objects.create( + headline=create_review_form.cleaned_data["headline"], + data=create_review_form.cleaned_data["data"], + author=request.user.person, + repository=repo, + filepath=create_review_form.cleaned_data["filename"], + commit=commit, + ) + review.save() + context = self.get_context_data(request, **kwargs) + messages.add_message(request, messages.SUCCESS, "The review was created successfully.") + return render( + request, + self.template_name, + { + **context, + "create_review_form": CreateReviewForm(), + "fetch_form": FetchForm(), + }, + ) + + +class NoteView(LoginRequiredMixin, FormMixin, DetailView): + template_name = "note.html" + model = Note + context_object_name = "note" + slug_field = "id" + slug_url_kwarg = "uuid" + form_class = CreateNoteForm + + def get_context_data(self, **kwargs): + context = super(NoteView, self).get_context_data(**kwargs) + context["form"] = CreateNoteForm() + return context + + def post(self, request, *args, **kwargs): + """Create a note""" + comment_form = self.get_form() + if comment_form.is_valid(): + comment_form.instance.acct = generate_webfinger(request.user.username) + comment_form.instance.reply_to = Note.objects.get(id=self.kwargs["uuid"]) + comment_form.save() + return self.get(request) + else: + return self.form_invalid(comment_form) + + +@method_decorator(has_valid_header, name="dispatch") +class UserProfile(View): + def get(self, request, *args, **kwargs): + """""" + try: + user = User.objects.get(username=kwargs["username"]) + except User.DoesNotExist: + return HttpResponseBadRequest("User doesn't exist") + + if request.GET.get("main-key"): + return HttpResponse( + user.person.public_key if hasattr(user, "person") else user.service.public_key + ) + + if hasattr(user, "person"): + return JsonResponse(user.person.to_ap, content_type=AP_CONTENT_TYPE) + elif hasattr(user, "service"): + return JsonResponse(user.service.to_ap, content_type=AP_CONTENT_TYPE) + else: + return HttpResponseBadRequest("Invalid type user") + + +class PersonUpdateView(UpdateView): + model = Person + fields = ["avatar", "summary"] + template_name = "update_profile.html" + slug_field = "user__username" + + def get_success_url(self): + return reverse_lazy("user-profile", kwargs={"slug": self.object.user.username}) + + def get_form(self, *args, **kwargs): + form = super(PersonUpdateView, self).get_form(*args, **kwargs) + form.fields["summary"].widget.attrs["class"] = "textarea" + form.fields["summary"].help_text = "" + form.fields["avatar"].label = "" + return form + + +@method_decorator(has_valid_header, name="dispatch") +class PackageProfile(View): + def get(self, request, *args, **kwargs): + """""" + try: + package = Package.objects.get(purl=kwargs["purl_string"]) + except Package.DoesNotExist: + return HttpResponseBadRequest("Invalid type user") + + if request.GET.get("main-key"): + return HttpResponse(package.public_key) + + return JsonResponse(package.to_ap, content_type=AP_CONTENT_TYPE) + + +@method_decorator(has_valid_header, name="dispatch") +class UserInbox(View): + def get(self, request, *args, **kwargs): + """You can GET from your inbox to read your latest messages + (client-to-server; this is like reading your social network stream)""" + if hasattr(request.user, "person") and request.user.username == kwargs["username"]: + purl_followers = [ + generate_webfinger(follow.package.purl) + for follow in Follow.objects.filter(person=request.user.person) + ] + note_list = Note.objects.filter(acct__in=purl_followers).order_by("updated_at__minute") + reviews = Review.objects.filter(author=request.user.person) + return JsonResponse( + {"notes": ap_collection(note_list), "reviews": ap_collection(reviews)}, + content_type=AP_CONTENT_TYPE, + ) + + def post(self, request, *args, **kwargs): + """You can POST to someone's inbox to send them a message + (server-to-server / federation only... this is federation!)""" + return NotImplementedError + + +@method_decorator(has_valid_header, name="dispatch") +class UserOutbox(View): + def get(self, request, *args, **kwargs): + """You can GET from someone's outbox to see what messages they've posted + (or at least the ones you're authorized to see). + (client-to-server and/or server-to-server)""" + try: + user = User.objects.get(username=kwargs["username"]) + except User.DoesNotExist: + user = None + + if hasattr(user, "person"): + notes = Note.objects.filter(acct=user.person.acct) + reviews = Review.objects.filter(author=user.person) + return JsonResponse( + { + "notes": ap_collection(notes), + "reviews": ap_collection(reviews), + }, + content_type=AP_CONTENT_TYPE, + ) + elif hasattr(user, "service"): + repos = Repository.objects.filter(admin=user.service) + return JsonResponse( + { + "repositories": ap_collection(repos), + }, + content_type=AP_CONTENT_TYPE, + ) + else: + return HttpResponseBadRequest("Can't find this user") + + @csrf_exempt + def post(self, request, *args, **kwargs): + """You can POST to your outbox to send messages to the world (client-to-server)""" + if request.user.is_authenticated and request.user.username == kwargs["username"]: + activity = create_activity_obj(request.body) + if activity: + return activity.handler() + + return HttpResponseBadRequest("Invalid message") + + +@method_decorator(has_valid_header, name="dispatch") +class PackageInbox(View): + def get(self, request, *args, **kwargs): + """ + You can GET from your inbox to read your latest messages + (client-to-server; this is like reading your social network stream) + """ + try: + package = Package.objects.get(purl=kwargs["purl_string"]) + except Package.DoesNotExist: + package = None + + if hasattr(request.user, "service") and package: + return JsonResponse( + { + "notes": ap_collection(package.notes.all()), + }, + content_type="application/activity+json", + ) + return HttpResponseBadRequest() + + @csrf_exempt + def post(self, request, *args, **kwargs): + """ + You can POST to someone's inbox to send them a message + (server-to-server / federation only... this is federation!) + """ + HttpSignature.verify_request(request, FEDERATED_CODE_PUBLIC_KEY) + activity = create_activity_obj(request.body) + activity_response = activity.handler() + return activity_response + + +@method_decorator(has_valid_header, name="dispatch") +class PackageOutbox(View): + def get(self, request, *args, **kwargs): + """GET from someone's outbox to see what messages they've posted + (or at least the ones you're authorized to see). + (client-to-server and/or server-to-server)""" + + actor = Package.objects.get(purl=kwargs["purl_string"]) + return JsonResponse( + {"notes": ap_collection(actor.notes)}, + content_type=AP_CONTENT_TYPE, + ) + + def post(self, request, *args, **kwargs): + """You can POST to your outbox to send messages to the world (client-to-server)""" + try: + actor = Package.objects.get(purl=kwargs["purl_string"]) + except Package.DoesNotExist: + return HttpResponseBadRequest("Invalid purl") + + if ( + request.user.is_authenticated + and hasattr(request.user, "service") + and actor.service == request.user.service + ): + activity = create_activity_obj(request.body) + return activity.handler() + return HttpResponseBadRequest("Invalid Message") + + +def redirect_repository(request, repository_id): + try: + repo = Repository.objects.get(id=repository_id) + except Repository.DoesNotExist: + raise Http404("Repository does not exist") + return redirect(repo.url) + + +def redirect_vulnerability(request, vulnerability_id): + try: + vul = Vulnerability.objects.get(id=vulnerability_id) + vul_filepath = os.path.join(vul.repo.path, + f"./aboutcode-vulnerabilities-{vulnerability_id[5:7]}/{vulnerability_id[10:12]}" + f"/{vulnerability_id}/{vulnerability_id}.yml") + with open(vul_filepath) as f: + return HttpResponse(json.dumps(f.read())) + + except Vulnerability.DoesNotExist: + return Http404("Vulnerability does not exist") + + +class UserFollowing(View): + def get(self, request, *args, **kwargs): + followings = Follow.objects.filter(person__user__username=self.kwargs["username"]) + return JsonResponse( + [full_reverse(following) for following in followings], + content_type=AP_CONTENT_TYPE, + ) + + +class PackageFollowers(View): + def get(self, request, *args, **kwargs): + followers = Follow.objects.filter(purl__string=self.kwargs["purl_string"]) + return JsonResponse( + [full_reverse(following) for following in followers], + content_type=AP_CONTENT_TYPE, + ) + + +@require_http_methods(["POST"]) +@csrf_exempt +def token(request): + payload = json.loads(request.body) + r = requests.post( + "http://127.0.0.1:8000/o/token/", + headers={"content-type": "application/x-www-form-urlencoded"}, + data={ + "grant_type": "password", + "username": payload["username"], + "password": payload["password"], + "client_id": FEDERATED_CODE_CLIENT_ID, + "client_secret": FEDERATED_CODE_CLIENT_SECRET, + }, + ) + return JsonResponse(json.loads(r.content), status=r.status_code, content_type=AP_CONTENT_TYPE) + + +@require_http_methods(["POST"]) +@csrf_exempt +def refresh_token(request): + payload = json.loads(request.body) + r = requests.post( + "http://127.0.0.1:8000/o/token/", + headers={"content-type": "application/x-www-form-urlencoded"}, + data={ + "grant_type": "refresh_token", + "refresh_token": payload["refresh_token"], + "client_id": FEDERATED_CODE_CLIENT_ID, + "client_secret": FEDERATED_CODE_CLIENT_SECRET, + }, + ) + return JsonResponse(json.loads(r.text), status=r.status_code, content_type=AP_CONTENT_TYPE) + + +@require_http_methods(["POST"]) +@csrf_exempt +def revoke_token(request): + payload = json.loads(request.body) + r = requests.post( + "http://127.0.0.1:8000/o/revoke_token/", + headers={"content-type": "application/x-www-form-urlencoded"}, + data={ + "token": payload["token"], + "client_id": FEDERATED_CODE_CLIENT_ID, + "client_secret": FEDERATED_CODE_CLIENT_SECRET, + }, + ) + return JsonResponse(json.loads(r.content), status=r.status_code, content_type=AP_CONTENT_TYPE) diff --git a/federatedcode/__init__.py b/federatedcode/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/federatedcode/asgi.py b/federatedcode/asgi.py new file mode 100644 index 0000000..bea1728 --- /dev/null +++ b/federatedcode/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for federatedcode project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "federatedcode.settings") + +application = get_asgi_application() diff --git a/federatedcode/settings.py b/federatedcode/settings.py new file mode 100644 index 0000000..78fb982 --- /dev/null +++ b/federatedcode/settings.py @@ -0,0 +1,158 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import os +from pathlib import Path + +import environ + +PROJECT_DIR = Path(__file__).resolve().parent +ROOT_DIR = PROJECT_DIR.parent +# Environment + +ENV_FILE = "federated_code/.env" +if not Path(ENV_FILE).exists(): + ENV_FILE = ROOT_DIR / ".env" + +env = environ.Env() +environ.Env.read_env(str(ENV_FILE)) + +FEDERATED_CODE_DOMAIN = env.str("FEDERATED_CODE_DOMAIN", "127.0.0.1:8000") +FEDERATED_CODE_GIT_PATH = env.str("FEDERATED_CODE_GIT_PATH", "") +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = "django-insecure-uoc-dv7+6%dy7c6(hc$6*z_m-#4y*jp1%-^*5)y&+i9-@j7zup" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"] + +# Application definition + +INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "oauth2_provider", + "fedcode", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "oauth2_provider.middleware.OAuth2TokenMiddleware", +] + +ROOT_URLCONF = "federatedcode.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + +WSGI_APPLICATION = "federatedcode.wsgi.application" + +# https://docs.djangoproject.com/en/4.1/ref/settings/#databases +# postgresql database +DATABASES = { + "default": { + "ENGINE": env.str("DB_ENGINE", "django.db.backends.postgresql"), + "HOST": env.str("POSTGRES_HOST", "127.0.0.1"), + "NAME": env.str("POSTGRES_DB_NAME", "federatedcode"), + "USER": env.str("POSTGRES_USER", "federatedcode"), + "PASSWORD": env.str("POSTGRES_PASSWORD", "federatedcode"), + "PORT": env.str("POSTGRES_PORT", "5432"), + } +} + +# Password validation +# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, +] + +REST_FRAMEWORK = { + "DEFAULT_AUTHENTICATION_CLASSES": ( + "oauth2_provider.contrib.rest_framework.OAuth2Authentication", + "rest_framework.authentication.SessionAuthentication", + ), + "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), +} + +OAUTH2_PROVIDER = { + "ACCESS_TOKEN_EXPIRE_SECONDS": 3600, + "REFRESH_TOKEN_EXPIRE_SECONDS": 3600 * 24 * 365, + "SCOPES": {"read": "Read scope", "write": "Write scope"}, +} + +AUTHENTICATION_BACKENDS = ( + "django.contrib.auth.backends.ModelBackend", + "oauth2_provider.backends.OAuth2Backend", +) +# Internationalization +# https://docs.djangoproject.com/en/4.1/topics/i18n/ + +LANGUAGE_CODE = "en-us" + +TIME_ZONE = "UTC" + +USE_I18N = True + +USE_TZ = True + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.1/howto/static-files/ + +STATIC_URL = 'static/' +# STATIC_ROOT = env.str("FEDERATED_CODE_STATIC_ROOT", "./") + +# Default primary key field type +# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + +MEDIA_URL = "/media/" +MEDIA_ROOT = os.path.join(BASE_DIR, "media") +AP_CONTENT_TYPE = "application/activity+json" diff --git a/federatedcode/urls.py b/federatedcode/urls.py new file mode 100644 index 0000000..5ec2220 --- /dev/null +++ b/federatedcode/urls.py @@ -0,0 +1,115 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +from django.conf import settings +from django.conf.urls.static import static +from django.contrib import admin +from django.urls import include +from django.urls import path + +from fedcode import views +from fedcode.views import CreateReview, logout, obj_vote +from fedcode.views import CreateSync +from fedcode.views import CreatGitView +from fedcode.views import FollowPackageView +from fedcode.views import HomeView +from fedcode.views import NoteView +from fedcode.views import PersonSignUp +from fedcode.views import PersonUpdateView +from fedcode.views import PersonView +from fedcode.views import PackageFollowers +from fedcode.views import PackageInbox +from fedcode.views import PackageListView +from fedcode.views import PackageOutbox +from fedcode.views import PackageProfile +from fedcode.views import PackageView +from fedcode.views import RepositoryListView +from fedcode.views import ReviewListView +from fedcode.views import ReviewView +from fedcode.views import UserFollowing +from fedcode.views import UserInbox +from fedcode.views import UserLogin +from fedcode.views import UserOutbox +from fedcode.views import UserProfile +from fedcode.views import WebfingerView +from fedcode.views import fetch_repository_file +from fedcode.views import redirect_repository +from fedcode.views import redirect_vulnerability + +urlpatterns = [ + path("admin/", admin.site.urls), + path(".well-known/webfinger", WebfingerView.as_view(), name="web-finger"), + path("", HomeView.as_view(), name="home-page"), + path("users/@", PersonView.as_view(), name="user-profile"), + path("users/@/edit", PersonUpdateView.as_view(), name="user-edit"), + path("purls/@/", PackageView.as_view(), name="purl-profile"), + path("purls/@/follow", FollowPackageView.as_view(), name="purl-follow"), + path("accounts/sign-up", PersonSignUp.as_view(), name="signup"), + path("accounts/login/", UserLogin.as_view(), name="login"), + path("accounts/logout", logout, name="logout"), + path("create-repo", CreatGitView.as_view(), name="repo-create"), + path("repo-list", RepositoryListView.as_view(), name="repo-list"), + path("purl-list", PackageListView.as_view(), name="purl-list"), + path( + "repository//create-review/", + CreateReview.as_view(), + name="review-create", + ), + path( + "repository//sync-repo/", + CreateSync.as_view(), + name="sync-activity", + ), + path("review-list", ReviewListView.as_view(), name="review-list"), + path("reviews//", ReviewView.as_view(), name="review-page"), + path("reviews//votes/", obj_vote, {'obj_type': 'review'}, name="review-votes"), + path("notes//votes/", obj_vote, {'obj_type': 'note'}, name="comment-votes"), + path("repository//", redirect_repository, name="repository-page"), + path( + "repository//fetch", + fetch_repository_file, + name="repository-fetch", + ), + path( + "vulnerability//", + redirect_vulnerability, + name="vulnerability-page", + ), + path("notes/", NoteView.as_view(), name="note-page"), + path("api/v0/users/@", UserProfile.as_view(), name="user-ap-profile"), + path( + "api/v0/purls/@/", + PackageProfile.as_view(), + name="purl-ap-profile", + ), + path("api/v0/users/@/inbox", UserInbox.as_view(), name="user-inbox"), + path("api/v0/users/@/outbox", UserOutbox.as_view(), name="user-outbox"), + path("api/v0/purls/@/inbox", PackageInbox.as_view(), name="purl-inbox"), + path( + "api/v0/purls/@/outbox", + PackageOutbox.as_view(), + name="purl-outbox", + ), + path( + "api/v0/users/@/following/", + UserFollowing.as_view(), + name="user-following", + ), + path( + "api/v0/purls/@/followers/", + PackageFollowers.as_view(), + name="purl-followers", + ), + path("auth/token/", views.token), + path("auth/refresh_token/", views.refresh_token), + path("auth/revoke_token/", views.revoke_token), + path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")), +] + +if settings.DEBUG: + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/federatedcode/wsgi.py b/federatedcode/wsgi.py new file mode 100644 index 0000000..a1000c1 --- /dev/null +++ b/federatedcode/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for federatedcode project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "federatedcode.settings") + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..54720d4 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "federatedcode.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml index cde7907..5ffd4c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,7 @@ norecursedirs = [ "tests/*/data" ] +DJANGO_SETTINGS_MODULE = "federatedcode.settings" python_files = "*.py" python_classes = "Test" @@ -50,3 +51,22 @@ addopts = [ "--strict-markers", "--doctest-modules" ] +[tool.black] +line-length = 100 +include = '\.pyi?$' +skip_gitignore = true +# 'extend-exclude' excludes files or directories in addition to the defaults +extend-exclude = ''' +( + ^/venv/.* + | ^/federatedcode/migrations/.* +) +''' + +[tool.isort] +profile = "black" +line_length = 100 +force_single_line = true +skip_gitignore = true +skip_glob = "federatedcode/migrations/*" + diff --git a/requirements-dev.txt b/requirements-dev.txt index e69de29..ae4151e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -0,0 +1,107 @@ +aboutcode-toolkit==10.1.0 +alabaster==0.7.13 +anyio==4.1.0 +asgiref==3.7.2 +attrs==23.1.0 +Babel==2.14.0 +black==23.7.0 +boolean.py==4.0 +certifi==2023.5.7 +cffi==1.15.1 +charset-normalizer==3.1.0 +click==8.1.7 +colorama==0.4.6 +cryptography==41.0.1 +dateparser==1.1.8 +Deprecated==1.2.14 +Django==5.0.1 +django-environ==0.11.2 +django-oauth-toolkit==2.3.0 +django-rest-framework==0.1.0 +djangorestframework==3.14.0 +docutils==0.20.1 +et-xmlfile==1.1.0 +exceptiongroup==1.1.1 +execnet==2.0.2 +gitdb==4.0.10 +GitPython==3.1.40 +gunicorn==21.2.0 +h11==0.14.0 +http-message-signatures==0.4.4 +http-sfv==0.9.8 +httpcore==0.17.3 +httpx==0.25.1 +idna==3.4 +imagesize==1.4.1 +importlib-metadata==7.0.1 +iniconfig==2.0.0 +isort==5.12.0 +jaraco.classes==3.3.0 +jeepney==0.8.0 +Jinja2==3.1.2 +jwcrypto==1.5.0 +keyring==24.3.0 +license-expression==30.2.0 +livereload==2.6.3 +markdown-it-py==3.0.0 +MarkupSafe==2.1.3 +mdurl==0.1.2 +more-itertools==10.1.0 +mypy-extensions==1.0.0 +nh3==0.2.15 +oauthlib==3.2.2 +openpyxl==3.1.2 +packageurl-python==0.11.1 +packaging==23.1 +pathspec==0.11.2 +Pillow==9.5.0 +pkginfo==1.9.6 +platformdirs==3.10.0 +pluggy==1.0.0 +psycopg==3.1.16 +psycopg-binary==3.1.16 +psycopg2-binary==2.9.9 +pycodestyle==2.11.1 +pycparser==2.21 +Pygments==2.17.2 +pytest==7.3.2 +pytest-django==4.5.2 +pytest-xdist==3.5.0 +python-dateutil==2.8.2 +pytz==2023.3 +PyYAML==6.0.1 +readme-renderer==42.0 +regex==2023.8.8 +requests==2.31.0 +requests-toolbelt==1.0.0 +rfc3986==2.0.0 +rich==13.7.0 +saneyaml==0.6.0 +SecretStorage==3.3.3 +six==1.16.0 +smmap==5.0.0 +sniffio==1.3.0 +snowballstemmer==2.2.0 +Sphinx==7.2.6 +sphinx-autobuild==2021.3.14 +sphinx-copybutton==0.5.2 +sphinx-reredirects==0.1.3 +sphinx-rtd-dark-mode==1.3.0 +sphinx-rtd-theme==2.0.0 +sphinxcontrib-applehelp==1.0.7 +sphinxcontrib-devhelp==1.0.5 +sphinxcontrib-htmlhelp==2.0.4 +sphinxcontrib-jquery==4.1 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.6 +sphinxcontrib-serializinghtml==1.1.9 +sqlparse==0.4.4 +tomli==2.0.1 +tornado==6.4 +twine==4.0.2 +typing_extensions==4.6.3 +tzlocal==5.0.1 +unidiff==0.7.5 +urllib3==2.0.3 +wrapt==1.15.0 +zipp==3.17.0 diff --git a/requirements.txt b/requirements.txt index e69de29..ae4151e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,107 @@ +aboutcode-toolkit==10.1.0 +alabaster==0.7.13 +anyio==4.1.0 +asgiref==3.7.2 +attrs==23.1.0 +Babel==2.14.0 +black==23.7.0 +boolean.py==4.0 +certifi==2023.5.7 +cffi==1.15.1 +charset-normalizer==3.1.0 +click==8.1.7 +colorama==0.4.6 +cryptography==41.0.1 +dateparser==1.1.8 +Deprecated==1.2.14 +Django==5.0.1 +django-environ==0.11.2 +django-oauth-toolkit==2.3.0 +django-rest-framework==0.1.0 +djangorestframework==3.14.0 +docutils==0.20.1 +et-xmlfile==1.1.0 +exceptiongroup==1.1.1 +execnet==2.0.2 +gitdb==4.0.10 +GitPython==3.1.40 +gunicorn==21.2.0 +h11==0.14.0 +http-message-signatures==0.4.4 +http-sfv==0.9.8 +httpcore==0.17.3 +httpx==0.25.1 +idna==3.4 +imagesize==1.4.1 +importlib-metadata==7.0.1 +iniconfig==2.0.0 +isort==5.12.0 +jaraco.classes==3.3.0 +jeepney==0.8.0 +Jinja2==3.1.2 +jwcrypto==1.5.0 +keyring==24.3.0 +license-expression==30.2.0 +livereload==2.6.3 +markdown-it-py==3.0.0 +MarkupSafe==2.1.3 +mdurl==0.1.2 +more-itertools==10.1.0 +mypy-extensions==1.0.0 +nh3==0.2.15 +oauthlib==3.2.2 +openpyxl==3.1.2 +packageurl-python==0.11.1 +packaging==23.1 +pathspec==0.11.2 +Pillow==9.5.0 +pkginfo==1.9.6 +platformdirs==3.10.0 +pluggy==1.0.0 +psycopg==3.1.16 +psycopg-binary==3.1.16 +psycopg2-binary==2.9.9 +pycodestyle==2.11.1 +pycparser==2.21 +Pygments==2.17.2 +pytest==7.3.2 +pytest-django==4.5.2 +pytest-xdist==3.5.0 +python-dateutil==2.8.2 +pytz==2023.3 +PyYAML==6.0.1 +readme-renderer==42.0 +regex==2023.8.8 +requests==2.31.0 +requests-toolbelt==1.0.0 +rfc3986==2.0.0 +rich==13.7.0 +saneyaml==0.6.0 +SecretStorage==3.3.3 +six==1.16.0 +smmap==5.0.0 +sniffio==1.3.0 +snowballstemmer==2.2.0 +Sphinx==7.2.6 +sphinx-autobuild==2021.3.14 +sphinx-copybutton==0.5.2 +sphinx-reredirects==0.1.3 +sphinx-rtd-dark-mode==1.3.0 +sphinx-rtd-theme==2.0.0 +sphinxcontrib-applehelp==1.0.7 +sphinxcontrib-devhelp==1.0.5 +sphinxcontrib-htmlhelp==2.0.4 +sphinxcontrib-jquery==4.1 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.6 +sphinxcontrib-serializinghtml==1.1.9 +sqlparse==0.4.4 +tomli==2.0.1 +tornado==6.4 +twine==4.0.2 +typing_extensions==4.6.3 +tzlocal==5.0.1 +unidiff==0.7.5 +urllib3==2.0.3 +wrapt==1.15.0 +zipp==3.17.0 diff --git a/setup.cfg b/setup.cfg index bd0e58a..963125b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -41,6 +41,66 @@ setup_requires = setuptools_scm[toml] >= 4 python_requires = >=3.7 install_requires = + Django>=4.2.2 + psycopg2-binary>=2.8.6 + djangorestframework>=3.12.4 + django-oauth-toolkit>=2.3.0 + django-rest-framework>=0.1.0 + djangorestframework>=3.14.0 + django-environ>=0.10.0 + gunicorn>=21.2.0 + GitPython>=3.1.31 + requests>=2.31.0 + saneyaml>=0.6.0 + # + httpx>=0.24.1 + http-message-signatures>=0.4.4 + + anyio==4.1.0 + asgiref==3.7.2 + attrs==23.1.0 + black==23.7.0 + certifi==2023.5.7 + cffi==1.15.1 + charset-normalizer==3.1.0 + click==8.1.7 + cryptography==41.0.1 + dateparser==1.1.8 + Deprecated==1.2.14 + exceptiongroup==1.1.1 + gitdb==4.0.10 + h11==0.14.0 + http-sfv==0.9.8 + httpcore==0.17.3 + idna==3.4 + iniconfig==2.0.0 + isort==5.12.0 + jwcrypto==1.5.0 + mypy-extensions==1.0.0 + oauthlib==3.2.2 + packageurl-python==0.11.1 + packaging==23.1 + pathspec==0.11.2 + Pillow==9.5.0 + platformdirs==3.10.0 + pluggy==1.0.0 + pycparser==2.21 + pytest==7.3.2 + pytest-django==4.5.2 + python-dateutil==2.8.2 + pytz==2023.3 + regex==2023.8.8 + saneyaml==0.6.0 + six==1.16.0 + smmap==5.0.0 + sniffio==1.3.0 + sqlparse==0.4.4 + tomli==2.0.1 + typing_extensions==4.6.3 + tzlocal==5.0.1 + unidiff==0.7.5 + urllib3==2.0.3 + wrapt==1.15.0 [options.packages.find] @@ -65,4 +125,5 @@ docs = sphinx-autobuild sphinx-rtd-dark-mode>=1.3.0 sphinx-copybutton + sphinx-autobuild>=2021.3.14 diff --git a/src/README.rst b/src/README.rst deleted file mode 100644 index ec651fc..0000000 --- a/src/README.rst +++ /dev/null @@ -1,2 +0,0 @@ -Put your Python source code (and installable data) in this directory. - diff --git a/tests/README.rst b/tests/README.rst deleted file mode 100644 index d94783e..0000000 --- a/tests/README.rst +++ /dev/null @@ -1,2 +0,0 @@ -Put your Python test modules in this directory. - diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..bdac1cd --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,8 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# diff --git a/tests/docker-compose-dev-test-federation.yml b/tests/docker-compose-dev-test-federation.yml new file mode 100644 index 0000000..958957e --- /dev/null +++ b/tests/docker-compose-dev-test-federation.yml @@ -0,0 +1,51 @@ +version: '3' + +services: + db1: + image: postgres:16 + env_file: + - ./docker-compose-dev-test-federation1.env + volumes: + - db_data1:/var/lib/postgresql/data1/ + db2: + image: postgres:16 + env_file: + - ./docker-compose-dev-test-federation2.env + volumes: + - db_data2:/var/lib/postgresql/data2/ + + federated_code1: + build: ../ + command: /bin/sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8001" + env_file: + - docker-compose-dev-test-federation1.env + volumes: + - /etc/federated_code1/:/etc/federated_code1/ + expose: + - 8001 + ports: + - "8001:8001" + depends_on: + - db1 + + federated_code2: + build: ../ + command: /bin/sh -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8002" + env_file: + - docker-compose-dev-test-federation2.env + volumes: + - /etc/federated_code2/:/etc/federated_code2/ + expose: + - 8002 + ports: + - "8002:8002" + depends_on: + - db2 + + +volumes: + db_data1: + db_data2: + federated_code1: + federated_code2: + diff --git a/tests/docker-compose-dev-test-federation1.env b/tests/docker-compose-dev-test-federation1.env new file mode 100644 index 0000000..5587232 --- /dev/null +++ b/tests/docker-compose-dev-test-federation1.env @@ -0,0 +1,12 @@ +FEDERATED_CODE_HOST=127.0.0.1 +FEDERATED_CODE_PORT=8000 +FEDERATED_CODE_DOMAIN=${FEDERATED_CODE_HOST}:${FEDERATED_CODE_PORT} + +POSTGRES_HOST=db1 +POSTGRES_DB=purl-sync +POSTGRES_USER=purl-sync +POSTGRES_PASSWORD=purl-sync + +FEDERATED_CODE_GIT_PATH="" +FEDERATED_CODE_CLIENT_ID="" +FEDERATED_CODE_CLIENT_SECRET="" \ No newline at end of file diff --git a/tests/docker-compose-dev-test-federation2.env b/tests/docker-compose-dev-test-federation2.env new file mode 100644 index 0000000..9d0ff82 --- /dev/null +++ b/tests/docker-compose-dev-test-federation2.env @@ -0,0 +1,12 @@ +FEDERATED_CODE_HOST=127.0.0.1 +FEDERATED_CODE_PORT=8000 +FEDERATED_CODE_DOMAIN=${FEDERATED_CODE_HOST}:${FEDERATED_CODE_PORT} + +POSTGRES_HOST=db2 +POSTGRES_DB=purl-sync +POSTGRES_USER=purl-sync +POSTGRES_PASSWORD=purl-sync + +FEDERATED_CODE_GIT_PATH="" +FEDERATED_CODE_CLIENT_ID="" +FEDERATED_CODE_CLIENT_SECRET="" \ No newline at end of file diff --git a/tests/test_activitypub.py b/tests/test_activitypub.py new file mode 100644 index 0000000..c6e43d3 --- /dev/null +++ b/tests/test_activitypub.py @@ -0,0 +1,258 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import json + +import pytest + +from fedcode.activitypub import AP_CONTEXT +from fedcode.activitypub import create_activity_obj +from fedcode.models import Follow +from fedcode.models import Note +from fedcode.models import Repository +from fedcode.models import Review + +from .test_models import follow +from .test_models import mute_post_save_signal +from .test_models import note +from .test_models import package +from .test_models import person +from .test_models import repo +from .test_models import service +from .test_models import vulnerability + + +@pytest.mark.django_db +def test_person_create_note(person): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Create", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "type": "Note", + "content": "we should fix this purl", + }, + } + ) + + activity = create_activity_obj(payload) + create_activity = activity.handler() + assert Note.objects.count() == 1 + note = Note.objects.get(acct=person.acct, content="we should fix this purl") + assert json.loads(create_activity.content) == { + "Location": f"https://127.0.0.1:8000/notes/{note.id}" + } + assert create_activity.status_code == 201 + + +@pytest.mark.django_db +def test_person_create_review(person, vulnerability, repo): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Create", + "actor": f"https://127.0.0.1:8000/api/v0/users/@ziad", + "object": { + "type": "Review", + "headline": "review vulnerablecode-data VCID-0000-0000-0000", + "repository": f"https://127.0.0.1:8000/repository/{repo.id}/", + "filepath": "/apache/httpd/VCID-0000-0000-0000.yml", + "commit": "104ccd6a7a41329b2953c96e52792a3d6a9ad8e5", + "content": "diff text", + }, + } + ) + + activity = create_activity_obj(payload) + create_activity = activity.handler() + assert Review.objects.count() == 1 + review = Review.objects.get( + headline="review vulnerablecode-data VCID-0000-0000-0000", + author=person, + repository=repo, + data="diff text", + filepath="/apache/httpd/VCID-0000-0000-0000.yml", + commit="104ccd6a7a41329b2953c96e52792a3d6a9ad8e5", + status=0, + ) + assert json.loads(create_activity.content) == { + "Location": f"https://127.0.0.1:8000/reviews/{review.id}/" + } + assert create_activity.status_code == 201 + + +@pytest.mark.django_db +def test_purl_create_note(package, service): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Create", + "actor": f"https://127.0.0.1:8000/api/v0/purls/@{package.purl}/", + "object": { + "type": "Note", + "content": "we should fix this purl", + }, + } + ) + activity = create_activity_obj(payload) + create_activity = activity.handler() + note = Note.objects.get(acct=package.acct, content="we should fix this purl") + assert json.loads(create_activity.content) == { + "Location": f"https://127.0.0.1:8000/notes/{note.id}" + } + assert create_activity.status_code == 201 + + +@pytest.mark.django_db +def test_service_create_repo(service): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Create", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{service.user.username}", + "object": { + "type": "Repository", + "url": "https://github.com/nexB/vulnerablecode-data", + }, + } + ) + activity = create_activity_obj(payload) + create_activity = activity.handler() + assert Repository.objects.count() == 1 + repo = Repository.objects.get( + url="https://github.com/nexB/vulnerablecode-data", + admin=service, + ) + assert json.loads(create_activity.content) == { + "Location": f"https://127.0.0.1:8000/repository/{repo.id}/" + } + assert create_activity.status_code == 201 + + +@pytest.mark.django_db +def test_person_follow_package(person, package): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Follow", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "type": "Package", + "id": f"https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + }, + } + ) + + activity = create_activity_obj(payload) + follow_activity = activity.handler() + assert Follow.objects.get(person=person, package=package) + assert Follow.objects.count() == 1 + + +@pytest.mark.django_db +def test_person_delete_note(person, note): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Delete", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "type": "Note", + "id": f"https://127.0.0.1:8000/notes/{note.id}", + }, + } + ) + + activity = create_activity_obj(payload) + delete_activity = activity.handler() + assert Note.objects.count() == 0 + assert json.loads(delete_activity.content) == { + "message": "The object has been deleted successfully" + } + assert delete_activity.status_code == 200 + + +@pytest.mark.django_db +def test_person_delete_note(person, note): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Delete", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "type": "Note", + "id": f"https://127.0.0.1:8000/notes/{note.id}", + }, + } + ) + + activity = create_activity_obj(payload) + delete_activity = activity.handler() + assert Note.objects.count() == 0 + + +@pytest.mark.django_db +def test_person_update_note(person, note): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Update", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "id": f"https://127.0.0.1:8000/notes/{note.id}", + "type": "Note", + "content": "Hello World!", + }, + } + ) + + activity = create_activity_obj(payload) + update_activity = activity.handler() + assert Note.objects.count() == 1 + note = Note.objects.get(id=note.id) + assert note.content == "Hello World!" + assert json.loads(update_activity.content) == note.to_ap + assert update_activity.status_code == 200 + + +@pytest.mark.django_db +def test_person_unfollow_package(person, package, follow): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "UnFollow", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "type": "Package", + "id": f"https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + }, + } + ) + + activity = create_activity_obj(payload) + follow_activity = activity.handler() + assert Follow.objects.count() == 0 + + +# @pytest.mark.django_db +# def test_person_sync_repo(service, repo): +# payload = json.dumps( +# { +# **AP_CONTEXT, +# "type": "Sync", +# "actor": f"https://127.0.0.1:8000/users/@{service.user.username}", +# "object": { +# "type": "Repository", +# "id": f"https://127.0.0.1:8000/repository/{repo.id}/", +# }, +# } +# ) +# +# activity = create_activity_obj(payload) +# sync_activity = activity.handler() diff --git a/tests/test_ap_api.py b/tests/test_ap_api.py new file mode 100644 index 0000000..ffcba4d --- /dev/null +++ b/tests/test_ap_api.py @@ -0,0 +1,363 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import datetime +import json +from datetime import datetime +from datetime import timedelta + +import pytest +from django.contrib.auth.models import User +from django.urls import reverse +from oauth2_provider.models import AccessToken +from oauth2_provider.models import Application +from rest_framework.test import APIClient + +from fedcode.activitypub import AP_CONTEXT +from fedcode.models import Follow +from fedcode.models import Note +from fedcode.models import Person +from fedcode.models import Review +from fedcode.models import Vulnerability +from fedcode.utils import generate_webfinger +from federatedcode.settings import AP_CONTENT_TYPE + +from .test_models import follow +from .test_models import mute_post_save_signal +from .test_models import note +from .test_models import package +from .test_models import person +from .test_models import repo +from .test_models import review +from .test_models import service +from .test_models import vulnerability + + +def create_token(user): + app = Application.objects.create( + client_type=Application.CLIENT_CONFIDENTIAL, + authorization_grant_type=Application.GRANT_PASSWORD, + redirect_uris="https://127.0.0.1:8000/", + name="purl-sync", + user=user, + ) + token = AccessToken.objects.create( + user=user, + scope="read write", + expires=datetime.now() + timedelta(seconds=500), + token="fake-access-key", + application=app, + ) + return f"Bearer {token}" + + +@pytest.mark.django_db +def test_get_ap_profile_user(person, service): + client = APIClient() + response_person = client.get( + reverse("user-ap-profile", args=[person.user.username]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + + response_service = client.get( + reverse("user-ap-profile", args=[service.user.username]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + + assert json.loads(response_person.content) == { + "type": "Person", + "name": "ziad", + "summary": "Hello World", + "following": "https://127.0.0.1:8000/api/v0/users/@ziad/following/", + "id": "https://127.0.0.1:8000/api/v0/users/@ziad", + "image": "https://127.0.0.1:8000/media/favicon-16x16.png", + "inbox": "https://127.0.0.1:8000/api/v0/users/@ziad/inbox", + "outbox": "https://127.0.0.1:8000/api/v0/users/@ziad/outbox", + "publicKey": { + "id": "https://127.0.0.1:8000/api/v0/users/@ziad", + "owner": "https://127.0.0.1:8000/api/v0/users/@ziad", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC " "KEY-----", + }, + } + + assert json.loads(response_service.content) == {"name": "vcio", "type": "Service"} + + +@pytest.mark.django_db +def test_get_ap_profile_package(package): + client = APIClient() + response = client.get( + reverse("purl-ap-profile", args=[package.purl]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + assert json.loads(response.content) == { + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "type": "Package", + "purl": "pkg:maven/org.apache.logging", + "name": "vcio", + "followers": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/followers/", + "inbox": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/inbox", + "outbox": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/outbox", + "publicKey": { + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "owner": "https://127.0.0.1:8000/api/v0/users/@vcio", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC " "KEY-----", + }, + } + + +@pytest.mark.django_db +def test_get_user_inbox_empty(person): + client = APIClient() + auth = create_token(person.user) + client.credentials(HTTP_AUTHORIZATION=auth) + response = client.get( + reverse("user-inbox", args=[person.user.username]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + + assert json.loads(response.content) == { + "notes": {"type": "OrderedCollection", "totalItems": 0, "orderedItems": []}, + "reviews": {"type": "OrderedCollection", "totalItems": 0, "orderedItems": []}, + } + + assert response.headers["Content-Type"] == AP_CONTENT_TYPE + assert response.status_code == 200 + + +@pytest.mark.django_db +def test_get_user_inbox(person, vulnerability, review, package): + note1 = Note.objects.create(acct=package.acct, content="yaml data1") + note2 = Note.objects.create(acct=package.acct, content="yaml data2") + Follow.objects.create(person=person, package=package) + + client = APIClient(enforce_csrf_checks=True) + auth = create_token(person.user) + client.credentials(HTTP_AUTHORIZATION=auth) + path = reverse("user-inbox", args=[person.user.username]) + response = client.get( + path, + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + + assert response.headers["Content-Type"] == AP_CONTENT_TYPE + assert response.status_code == 200 + assert json.loads(response.content) == { + "notes": { + "type": "OrderedCollection", + "totalItems": 2, + "orderedItems": [ + { + "id": f"https://127.0.0.1:8000/notes/{note1.id}", + "type": "Note", + "author": "pkg:maven/org.apache.logging@127.0.0.1:8000", + "content": "yaml data1", + }, + { + "id": f"https://127.0.0.1:8000/notes/{note2.id}", + "type": "Note", + "author": "pkg:maven/org.apache.logging@127.0.0.1:8000", + "content": "yaml data2", + }, + ], + }, + "reviews": { + "type": "OrderedCollection", + "totalItems": 1, + "orderedItems": [ + { + "id": f"https://127.0.0.1:8000/reviews/{review.id}/", + "type": "Review", + "author": "https://127.0.0.1:8000/api/v0/users/@ziad", + "headline": review.headline, + "repository": str(review.repository.id), + "filepath": review.filepath, + "content": review.data, + "commit": review.commit, + "comments": { + "type": "OrderedCollection", + "totalItems": 0, + "orderedItems": [], + }, + "published": review.created_at.strftime("%Y-%m-%dT%H:%M:%S.%fZ")[:-4] + "Z", + "updated": review.updated_at.strftime("%Y-%m-%dT%H:%M:%S.%fZ")[:-4] + "Z", + } + ], + }, + } + + +@pytest.mark.django_db +def test_get_user_outbox_empty(person): + client = APIClient() + path = reverse( + "user-outbox", + args=[person.user.username], + ) + response = client.get( + path, + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + assert json.loads(response.content) == { + "notes": {"type": "OrderedCollection", "totalItems": 0, "orderedItems": []}, + "reviews": {"type": "OrderedCollection", "totalItems": 0, "orderedItems": []}, + } + assert response.headers["Content-Type"] == AP_CONTENT_TYPE + assert response.status_code == 200 + + +@pytest.mark.django_db +def test_get_user_outbox(person, vulnerability, review, note): + client = APIClient(enforce_csrf_checks=True) + response = client.get( + reverse("user-outbox", args=[person.user.username]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + assert json.loads(response.content) == { + "notes": {"type": "OrderedCollection", "totalItems": 0, "orderedItems": []}, + "reviews": { + "type": "OrderedCollection", + "totalItems": 1, + "orderedItems": [ + { + "id": f"https://127.0.0.1:8000/reviews/{review.id}/", + "type": "Review", + "author": f"https://127.0.0.1:8000/api/v0/users/@{review.author.user.username}", + "headline": review.headline, + "repository": str(review.repository.id), + "filepath": review.filepath, + "content": review.data, + "commit": review.commit, + "comments": { + "type": "OrderedCollection", + "totalItems": 0, + "orderedItems": [], + }, + "published": review.created_at.strftime("%Y-%m-%dT%H:%M:%S.%fZ")[:-4] + "Z", + "updated": review.updated_at.strftime("%Y-%m-%dT%H:%M:%S.%fZ")[:-4] + "Z", + } + ], + }, + } + + assert response.headers["Content-Type"] == AP_CONTENT_TYPE + assert response.status_code == 200 + + +@pytest.mark.django_db +def test_post_user_outbox(person): + client = APIClient() + auth = create_token(person.user) + client.credentials(HTTP_AUTHORIZATION=auth) + path = reverse("user-outbox", args=[person.user.username]) + response = client.post( + path, + { + **AP_CONTEXT, + "type": "Create", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "type": "Note", + "content": "we should fix this purl", + }, + }, + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + assert Note.objects.count() == 1 + + +@pytest.mark.django_db +def test_get_package_inbox_empty(package, service): + client = APIClient() + auth = create_token(service.user) + client.credentials(HTTP_AUTHORIZATION=auth) + + response = client.get( + reverse("purl-inbox", args=[package.purl]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + + assert json.loads(response.content) == { + "notes": {"type": "OrderedCollection", "totalItems": 0, "orderedItems": []}, + } + + +@pytest.mark.django_db +def test_get_package_inbox(package, service): + note1 = Note.objects.create( + acct=package.acct, + content="""purl: pkg:maven/org.apache.logging@2.23-r0?arch=aarch64&distroversion=edge&reponame=community + affected_by_vulnerabilities: [] fixing_vulnerabilities: []""", + ) + package.notes.add(note1) + client = APIClient() + auth = create_token(service.user) + client.credentials(HTTP_AUTHORIZATION=auth) + + response = client.get( + reverse("purl-inbox", args=[package.purl]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + + assert json.loads(response.content) == { + "notes": { + "orderedItems": [ + { + "author": "pkg:maven/org.apache.logging@127.0.0.1:8000", + "content": "purl: " + "pkg:maven/org.apache.logging@2.23-r0?arch=aarch64&distroversion=edge&reponame=community\n" + " affected_by_vulnerabilities: " + "[] fixing_vulnerabilities: []", + "id": f"https://127.0.0.1:8000/notes/{note1.id}", + "type": "Note", + } + ], + "totalItems": 1, + "type": "OrderedCollection", + } + } + + +@pytest.mark.django_db +def test_get_package_outbox(service, package): + client = APIClient() + auth = create_token(service.user) + client.credentials(HTTP_AUTHORIZATION=auth) + note1 = Note.objects.create(acct=package.acct, content="yaml data1") + package.notes.add(note1) + + response = client.get( + reverse("purl-outbox", args=[package.purl]), + headers={"Content-Type": AP_CONTENT_TYPE}, + format="json", + ) + + assert json.loads(response.content) == { + "notes": { + "orderedItems": [ + { + "author": "pkg:maven/org.apache.logging@127.0.0.1:8000", + "content": "yaml data1", + "id": f"https://127.0.0.1:8000/notes/{note1.id}", + "type": "Note", + } + ], + "totalItems": 1, + "type": "OrderedCollection", + } + } diff --git a/tests/test_data/mock_request_remote_person.json b/tests/test_data/mock_request_remote_person.json new file mode 100644 index 0000000..b597c50 --- /dev/null +++ b/tests/test_data/mock_request_remote_person.json @@ -0,0 +1,15 @@ +{ + "following": "https://127.0.0.2:8000/api/v0/users/@ziad/following/", + "id": "https://127.0.0.2:8000/api/v0/users/@ziad", + "image": "https://127.0.0.2:8000/media/favicon16x16.png", + "inbox": "https://127.0.0.2:8000/api/v0/users/@ziad/inbox", + "name": "ziad", + "outbox": "https://127.0.0.2:8000/api/v0/users/@ziad/outbox", + "publicKey": { + "id": "https://127.0.0.2:8000/api/v0/users/@ziad", + "owner": "https://127.0.0.2:8000/api/v0/users/@ziad", + "publicKeyPem": "BEGIN PUBLIC KEY...END PUBLIC KEY" + }, + "summary": "Hello World", + "type": "Person" +} \ No newline at end of file diff --git a/tests/test_data/mock_request_remote_person_webfinger.json b/tests/test_data/mock_request_remote_person_webfinger.json new file mode 100644 index 0000000..4c7dad1 --- /dev/null +++ b/tests/test_data/mock_request_remote_person_webfinger.json @@ -0,0 +1,15 @@ +{ + "subject": "remoteziad@127.0.0.2:8000", + "links": [ + { + "rel": "https://webfinger.net/rel/profilepage", + "type": "text/html", + "href": "https://127.0.0.2:8000/users/@ziad" + }, + { + "rel": "self", + "type": "application/activity+json", + "href": "https://127.0.0.2:8000/api/v0/users/@ziad" + } + ] +} \ No newline at end of file diff --git a/tests/test_data/mock_request_remote_purl.json b/tests/test_data/mock_request_remote_purl.json new file mode 100644 index 0000000..4835fb5 --- /dev/null +++ b/tests/test_data/mock_request_remote_purl.json @@ -0,0 +1,16 @@ +{ + "followers": "https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging/followers/", + "id": "https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "image": "https://127.0.0.2:8000/media/favicon16x16.png", + "inbox": "https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging/inbox", + "name": "vcio", + "string": "pkg:maven/org.apache.logging", + "outbox": "https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging/outbox", + "publicKey": { + "id": "https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "owner": "https://127.0.0.2:8000/api/v0/users/@vcio", + "publicKeyPem": "BEGIN PUBLIC KEY...END PUBLIC KEY" + }, + "type": "Package", + "purl": "pkg:maven/org.apache.logging" +} \ No newline at end of file diff --git a/tests/test_data/mock_request_remote_purl_webfinger.json b/tests/test_data/mock_request_remote_purl_webfinger.json new file mode 100644 index 0000000..79d0ca2 --- /dev/null +++ b/tests/test_data/mock_request_remote_purl_webfinger.json @@ -0,0 +1,15 @@ +{ + "subject": "acct:pkg:maven/org.apache.logging@127.0.0.2:8000", + "links": [ + { + "rel": "https://webfinger.net/rel/profilepage", + "type": "text/html", + "href": "https://127.0.0.2:8000/purls/@pkg:maven/org.apache.logging" + }, + { + "rel": "self", + "type": "application/activity+json", + "href": "https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging" + } + ] +} \ No newline at end of file diff --git a/tests/test_federation.py b/tests/test_federation.py new file mode 100644 index 0000000..2b3985e --- /dev/null +++ b/tests/test_federation.py @@ -0,0 +1,142 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import json +from unittest import mock + +import pytest + +from fedcode.activitypub import AP_CONTEXT +from fedcode.activitypub import create_activity_obj +from fedcode.models import Follow +from fedcode.models import Note +from fedcode.models import RemoteActor +from fedcode.utils import file_data + +from .test_models import package +from .test_models import person +from .test_models import remote_person +from .test_models import service + + +@mock.patch("httpx.Client") +@mock.patch("requests.get") +@pytest.mark.django_db +def test_remote_person_follow_package(mock_get, _, package): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Follow", + "actor": "https://127.0.0.2:8000/api/v0/users/@ziad", + "object": { + "type": "Package", + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + }, + "to": ["https://127.0.0.2:8000/api/v0/users/@ziad"], + } + ) + + mock_request_remote_person_webfinger = mock.Mock(status_code=200) + mock_request_remote_person_webfinger.json.return_value = file_data( + "tests/test_data/mock_request_remote_person_webfinger.json" + ) + + mock_request_remote_person = mock.Mock(status_code=200) + mock_request_remote_person.json.return_value = file_data( + "tests/test_data/mock_request_remote_person.json" + ) + + mock_request_server_to_server = mock.Mock(status_code=200) + + mock_get.side_effect = [ + mock_request_remote_person_webfinger, + mock_request_remote_person, + mock_request_server_to_server, + ] + + activity = create_activity_obj(payload) + activity_response = activity.handler() + remote_person = RemoteActor.objects.get( + url="https://127.0.0.2:8000/api/v0/users/@ziad", username="ziad" + ).person + + assert Follow.objects.get(person=remote_person, package=package) + assert Follow.objects.count() == 1 + + +@mock.patch("httpx.Client") +@mock.patch("requests.get") +@pytest.mark.django_db +def test_person_follow_remote_package(mock_get, _, person): + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Follow", + "actor": f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}", + "object": { + "type": "Package", + "id": "https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + }, + "to": [f"https://127.0.0.1:8000/api/v0/users/@{person.user.username}"], + } + ) + + activity = create_activity_obj(payload) + mock_request_remote_package_webfinger = mock.Mock(status_code=200) + mock_request_remote_package_webfinger.json.return_value = file_data( + "tests/test_data/mock_request_remote_purl_webfinger.json" + ) + + mock_request_remote_package = mock.Mock(status_code=200) + mock_request_remote_package.json.return_value = file_data( + "tests/test_data/mock_request_remote_purl.json" + ) + mock_request_server_to_server = mock.Mock(status_code=200) + + mock_get.side_effect = [ + mock_request_remote_package_webfinger, + mock_request_remote_package, + mock_request_server_to_server, + ] + + follow_activity = activity.handler() + remote_package = RemoteActor.objects.get( + url="https://127.0.0.2:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + username="vcio", + ).package + + assert Follow.objects.get(person=person, package=remote_package) + assert Follow.objects.count() == 1 + + +@pytest.mark.django_db +@mock.patch("httpx.Client") +def test_package_with_remote_follower_create_note(mock_get, package, remote_person): + Follow.objects.create(package=package, person=remote_person) + payload = json.dumps( + { + **AP_CONTEXT, + "type": "Create", + "actor": f"https://127.0.0.1:8000/api/v0/purls/@{package.purl}/", + "object": { + "type": "Note", + "content": "we should fix this purl", + }, + "to": ["https://127.0.0.1/remote-user/"], + } + ) + activity = create_activity_obj(payload) + create_activity = activity.handler() + note = Note.objects.get(acct=package.acct, content="we should fix this purl") + assert json.loads(create_activity.content) == { + "Location": f"https://127.0.0.1:8000/notes/{note.id}" + } + assert create_activity.status_code == 201 + + mock_get.status_code.return_value = 200 + mock_get.json.return_value = {} diff --git a/tests/test_importer.py b/tests/test_importer.py new file mode 100644 index 0000000..6be1d4d --- /dev/null +++ b/tests/test_importer.py @@ -0,0 +1,87 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import pytest + +from fedcode.importer import Importer +from fedcode.models import Note +from fedcode.models import Package +from fedcode.models import Vulnerability + +from .test_models import mute_post_save_signal +from .test_models import repo +from .test_models import service + + +@pytest.mark.skip(reason="Need a real git repo to test the importer") +@pytest.mark.django_db +def test_simple_importer(service, repo, mute_post_save_signal): + # just add all packages and vulnerabilities + repo.path = "/home/ziad/vul-sample/repo1" + importer = Importer(repo, service) + importer.run() + + assert Note.objects.count() > 1 + assert Vulnerability.objects.count() > 1 + assert Package.objects.count() > 1 + assert repo.last_imported_commit + + note_n = Note.objects.count() + vul_n = Vulnerability.objects.count() + purl_n = Package.objects.count() + last_imported_commit = repo.last_imported_commit + + # Run importer again without add any new data + importer = Importer(repo, service) + importer.run() + + assert note_n == Note.objects.count() + assert vul_n == Vulnerability.objects.count() + assert purl_n == Package.objects.count() + assert last_imported_commit == repo.last_imported_commit + + # Edit last_imported_commit + repo.last_imported_commit = "c8de84af0a7c11bf151e96142ce711824648ec41" + repo.save() + importer = Importer(repo, service) + importer.run() + + +@pytest.mark.skip(reason="Need a real git repo to test the importer") +@pytest.mark.django_db +def test_complex_importer(service, repo, mute_post_save_signal): + # repo with 1 commit + repo.path = "/home/ziad/vul-sample/repo1" + importer = Importer(repo, service) + importer.run() + + assert Note.objects.count() > 1 + assert Vulnerability.objects.count() > 1 + assert Package.objects.count() > 1 + assert repo.last_imported_commit + + note_n = Note.objects.count() + vul_n = Vulnerability.objects.count() + purl_n = Package.objects.count() + last_imported_commit = repo.last_imported_commit + + # Run importer again without add any new data + # the same repo with 2 commit ( after pull ) + repo.path = "/home/ziad/vul-sample/repo2" + importer = Importer(repo, service) + importer.run() + + assert note_n > Note.objects.count() + assert vul_n > Vulnerability.objects.count() + assert purl_n > Package.objects.count() + + # Edit last_imported_commit + repo.last_imported_commit = "9c3ccee39baef6017d9152367402de9909eadd72" + repo.save() + importer = Importer(repo, service) + importer.run() diff --git a/tests/test_models.py b/tests/test_models.py new file mode 100644 index 0000000..dcc51d3 --- /dev/null +++ b/tests/test_models.py @@ -0,0 +1,169 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# + +import pytest +from django.contrib.auth.models import User +from django.db.models.signals import post_save + +from fedcode.models import Follow +from fedcode.models import Note +from fedcode.models import Package +from fedcode.models import Person +from fedcode.models import RemoteActor +from fedcode.models import Repository +from fedcode.models import Reputation +from fedcode.models import Review +from fedcode.models import Service +from fedcode.models import Vulnerability + + +@pytest.fixture +def service(db): + user = User.objects.create( + username="vcio", + email="vcio@nexb.com", + password="complex-password", + ) + return Service.objects.create( + user=user, + ) + + +@pytest.fixture +def package(db, service): + return Package.objects.create( + purl="pkg:maven/org.apache.logging", + service=service, + ) + + +@pytest.fixture +def remote_purl(db): + remote_user1 = RemoteActor.objects.create(url="127.0.0.1", username="remote-ziad") + return Package.objects.create(remote_user=remote_user1, string="pkg:maven/org.apache.logging") + + +@pytest.fixture +def person(db): + user1 = User.objects.create( + username="ziad", + email="ziad@nexb.com", + password="complex-password", + ) + return Person.objects.create(user=user1, summary="Hello World", public_key="PUBLIC_KEY") + + +@pytest.fixture +def remote_person(db): + remote_user1 = RemoteActor.objects.create(url="127.0.0.2", username="remote-ziad") + return Person.objects.create(remote_actor=remote_user1) + + +def test_person(person): + assert person.user.username == "ziad" + assert person.user.email == "ziad@nexb.com" + assert person.summary == "Hello World" + assert person.public_key == "PUBLIC_KEY" + + +def test_remote_person(remote_person): + assert remote_person.remote_actor.url == "127.0.0.2" + assert remote_person.remote_actor.username == "remote-ziad" + + +def test_purl(package, service): + assert package.service == service + assert package.purl == "pkg:maven/org.apache.logging" + assert Package.objects.count() == 1 + + +@pytest.fixture +def repo(db, service, mute_post_save_signal): + """Simple Git Repository""" + return Repository.objects.create( + url="https://github.com/nexB/fake-repo", + path="./review/tests/test_data/test_git_repo_v1", + admin=service, + ) + + +@pytest.fixture +def vulnerability(db, repo): + return Vulnerability.objects.create( + id="VCID-1155-4sem-aaaq", + repo=repo, + ) + + +@pytest.fixture +def review(db, repo, person): + return Review.objects.create( + headline="Review title 1", + author=person, + repository=repo, + filepath="/apache/httpd/VCID-1a68-fd5t-aaam.yml", + data="text diff", + commit="49d8c5fd4bea9488186a832b13ebdc83484f1b6a", + ) + + +@pytest.fixture +def note(db): + return Note.objects.create( + acct="ziad@vcio", + content="Comment #1", + ) + + +@pytest.fixture +def follow(db, package, person): + return Follow.objects.create(package=package, person=person) + + +@pytest.fixture +def rep(db, note): + return Reputation.objects.create( + voter="ziad@vcio", + positive=True, + content_object=note, + ) + + +def test_follow(follow, package, person): + assert follow.package.purl == package.purl + assert follow.person.user == person.user + + +def test_review(review, person, repo): + assert review.headline == "Review title 1" + assert review.author == person + assert review.repository == repo + assert review.filepath == "/apache/httpd/VCID-1a68-fd5t-aaam.yml" + assert review.data == "text diff" + assert review.status == 0 + assert review.commit == "49d8c5fd4bea9488186a832b13ebdc83484f1b6a" + + +def test_reputation(rep, note): + assert rep.voter == "ziad@vcio" + assert rep.positive is True + assert rep.content_object == note + + +def test_vulnerability(vulnerability, repo): + assert vulnerability.id == "VCID-1155-4sem-aaaq" + assert vulnerability.repo == repo + + +@pytest.fixture(autouse=True) +def mute_post_save_signal(request): + """ + copied from https://www.cameronmaske.com/muting-django-signals-with-a-pytest-fixture/ + """ + post_save.receivers = [] diff --git a/tests/test_skeleton_codestyle.py b/tests/test_skeleton_codestyle.py index 2eb6e55..95fcb9f 100644 --- a/tests/test_skeleton_codestyle.py +++ b/tests/test_skeleton_codestyle.py @@ -7,9 +7,9 @@ # See https://aboutcode.org for more information about nexB OSS projects. # +import configparser import subprocess import unittest -import configparser class BaseTests(unittest.TestCase): diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..22104dd --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,85 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import json +import uuid + +import pytest + +from fedcode.activitypub import AP_CONTEXT +from fedcode.activitypub import Activity +from fedcode.activitypub import create_activity_obj +from fedcode.utils import check_purl_actor +from fedcode.utils import full_resolve +from fedcode.utils import full_reverse + + +@pytest.mark.parametrize( + "payload,expected", + [ + ( + { + **AP_CONTEXT, + "type": "Create", + "actor": "https://dustycloud.org/chris/", + "object": "https://rhiaro.co.uk/2016/05/minimal-activitypub", + }, + Activity( + type="Create", + actor="https://dustycloud.org/chris/", + object="https://rhiaro.co.uk/2016/05/minimal-activitypub", + ), + ), + ( + { + **AP_CONTEXT, + "id": "https://example.com/api/activity/2", + "type": "Update", + "actor": "https://example.com/chris/", + "object": { + "type": "Note", + "id": "https://example.com/note/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "actor": "https://example.com/user/@user1", + "content": "we should fix purl", + }, + }, + Activity( + id="https://example.com/api/activity/2", + type="Update", + actor="https://example.com/chris/", + object={ + "type": "Note", + "id": "https://example.com/note/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", + "actor": "https://example.com/user/@user1", + "content": "we should fix purl", + }, + ), + ), + ], +) +def test_load_activity(payload, expected): + json_payload = json.dumps(payload) + assert create_activity_obj(json_payload) == expected + + +def test_full_reverse(): + assert ( + full_reverse("note-page", "7e676ad1-995d-405c-a829-cb39813c74e5") + == "https://127.0.0.1:8000/notes/7e676ad1-995d-405c-a829-cb39813c74e5" + ) + + +def test_full_resolve(): + assert full_resolve(f"https://127.0.0.1:8000/notes/7e676ad1-995d-405c-a829-cb39813c74e5") == ( + {"uuid": uuid.UUID("7e676ad1-995d-405c-a829-cb39813c74e5")}, + "note-page", + ) + + +def test_check_purl_actor(): + assert check_purl_actor("pkg:maven/org.apache.logging") diff --git a/tests/test_vocabulary_toap.py b/tests/test_vocabulary_toap.py new file mode 100644 index 0000000..b62d179 --- /dev/null +++ b/tests/test_vocabulary_toap.py @@ -0,0 +1,94 @@ +import pytest + +from .test_models import mute_post_save_signal +from .test_models import note +from .test_models import package +from .test_models import person +from .test_models import rep +from .test_models import repo +from .test_models import review +from .test_models import service +from .test_models import vulnerability + + +@pytest.mark.django_db +def test_actors_to_ap(person, package, service): + assert person.to_ap == { + "id": "https://127.0.0.1:8000/api/v0/users/@ziad", + "type": "Person", + "name": "ziad", + "summary": "Hello World", + "following": "https://127.0.0.1:8000/api/v0/users/@ziad/following/", + "image": "https://127.0.0.1:8000/media/favicon-16x16.png", + "inbox": "https://127.0.0.1:8000/api/v0/users/@ziad/inbox", + "outbox": "https://127.0.0.1:8000/api/v0/users/@ziad/outbox", + "publicKey": { + "id": "https://127.0.0.1:8000/api/v0/users/@ziad", + "owner": "https://127.0.0.1:8000/api/v0/users/@ziad", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", + }, + } + assert package.to_ap == { + "id": f"https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "type": "Package", + "purl": "pkg:maven/org.apache.logging", + "name": "vcio", + "followers": f"https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/followers/", + "inbox": f"https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/inbox", + "outbox": f"https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/outbox", + "publicKey": { + "id": "https://127.0.0.1:8000/api/v0/purls/@pkg:maven/org.apache.logging/", + "owner": "https://127.0.0.1:8000/api/v0/users/@vcio", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----", + }, + } + assert service.to_ap == { + "type": "Service", + "name": "vcio", + } + + +@pytest.mark.django_db +def test_objects_to_ap(repo, review, vulnerability, note, rep, mute_post_save_signal): + assert repo.to_ap == { + "id": f"https://127.0.0.1:8000/repository/{repo.id}/", + "type": "Repository", + "url": "https://github.com/nexB/fake-repo", + } + + assert review.to_ap == { + "id": f"https://127.0.0.1:8000/reviews/{review.id}/", + "type": "Review", + "headline": review.headline, + "content": review.data, + "author": f"https://127.0.0.1:8000/api/v0/users/@{review.author.user.username}", + "comments": {"orderedItems": [], "totalItems": 0, "type": "OrderedCollection"}, + "commit": review.commit, + "published": review.created_at, + "updated": review.updated_at, + "repository": str(repo.id), + "filepath": review.filepath, + } + assert vulnerability.to_ap == { + "id": f"https://127.0.0.1:8000/vulnerability/{vulnerability.id}/", + "type": "Vulnerability", + "repository": f"https://127.0.0.1:8000/repository/{vulnerability.repo.id}/", + } + + assert note.to_ap == { + "type": "Note", + "id": f"https://127.0.0.1:8000/notes/{note.id}", + "author": note.acct, + "content": note.content, + } + + assert rep.to_ap == { + "type": "Like", + "actor": "ziad@vcio", + "object": { + "type": "Note", + "id": f"https://127.0.0.1:8000/notes/{note.id}", + "author": note.acct, + "content": note.content, + }, + } diff --git a/tests/test_webfinger.py b/tests/test_webfinger.py new file mode 100644 index 0000000..af0839c --- /dev/null +++ b/tests/test_webfinger.py @@ -0,0 +1,86 @@ +# +# Copyright (c) nexB Inc. and others. All rights reserved. +# VulnerableCode is a trademark of nexB Inc. +# SPDX-License-Identifier: Apache-2.0 +# See http://www.apache.org/licenses/LICENSE-2.0 for the license text. +# See https://github.com/nexB/vulnerablecode for support or download. +# See https://aboutcode.org for more information about nexB OSS projects. +# +import json + +import pytest +from django.test import Client + +from fedcode.utils import generate_webfinger +from federatedcode.settings import FEDERATED_CODE_DOMAIN + +from .test_models import package +from .test_models import person +from .test_models import service + + +@pytest.mark.django_db +def test_webfinger(person, service, package): + client = Client() + person_acct = "acct:" + generate_webfinger(person.user.username) + response_person = client.get( + f"/.well-known/webfinger?resource={person_acct}", + ) + + service_acct = "acct:" + generate_webfinger(service.user.username) + response_service = client.get( + f"/.well-known/webfinger?resource={service_acct}", + ) + + package_acct = "acct:" + generate_webfinger(package.purl) + response_purl = client.get( + f"/.well-known/webfinger?resource={package_acct}", + ) + + assert json.loads(response_person.content) == { + "subject": person_acct, + "links": [ + { + "rel": "https://webfinger.net/rel/profile-page", + "type": "text/html", + "href": f"https://{FEDERATED_CODE_DOMAIN}/users/@{person.user.username}", + }, + { + "rel": "self", + "type": "application/activity+json", + "href": f"https://{FEDERATED_CODE_DOMAIN}/api/v0/users/@{person.user.username}", + }, + ], + } + + assert json.loads(response_service.content) == { + "subject": service_acct, + "links": [ + { + "rel": "https://webfinger.net/rel/profile-page", + "type": "text/html", + "href": f"https://{FEDERATED_CODE_DOMAIN}/users/@{service.user.username}", + }, + { + "rel": "self", + "type": "application/activity+json", + "href": f"https://{FEDERATED_CODE_DOMAIN}/api/v0/users/@{service.user.username}", + }, + ], + } + + assert json.loads(response_purl.content) == { + "subject": package_acct, + "links": [ + { + "rel": "https://webfinger.net/rel/profile-page", + "type": "text/html", + "href": f"https://{FEDERATED_CODE_DOMAIN}/purls/@{ package.purl }", + }, + { + "rel": "self", + "type": "application/activity+json", + "href": f"https://{FEDERATED_CODE_DOMAIN}/api/v0/purls/@{ package.purl }", + }, + ], + }