diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 000000000..9f17c2627 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 1f0b44b656768a3e8e8d7e330572fb3a +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/changelog.doctree b/.doctrees/changelog.doctree new file mode 100644 index 000000000..cd4fda31c Binary files /dev/null and b/.doctrees/changelog.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle new file mode 100644 index 000000000..a17730c75 Binary files /dev/null and b/.doctrees/environment.pickle differ diff --git a/.doctrees/faq.doctree b/.doctrees/faq.doctree new file mode 100644 index 000000000..29429f348 Binary files /dev/null and b/.doctrees/faq.doctree differ diff --git a/.doctrees/hardware.doctree b/.doctrees/hardware.doctree new file mode 100644 index 000000000..fe6f5fee6 Binary files /dev/null and b/.doctrees/hardware.doctree differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 000000000..c6223f001 Binary files /dev/null and b/.doctrees/index.doctree differ diff --git a/.doctrees/installation.doctree b/.doctrees/installation.doctree new file mode 100644 index 000000000..a15ff6051 Binary files /dev/null and b/.doctrees/installation.doctree differ diff --git a/.doctrees/reference.doctree b/.doctrees/reference.doctree new file mode 100644 index 000000000..32828a944 Binary files /dev/null and b/.doctrees/reference.doctree differ diff --git a/.doctrees/reference_description_file.doctree b/.doctrees/reference_description_file.doctree new file mode 100644 index 000000000..09ef82193 Binary files /dev/null and b/.doctrees/reference_description_file.doctree differ diff --git a/.doctrees/reference_developer_guide.doctree b/.doctrees/reference_developer_guide.doctree new file mode 100644 index 000000000..a46344427 Binary files /dev/null and b/.doctrees/reference_developer_guide.doctree differ diff --git a/.doctrees/reference_task_qc.doctree b/.doctrees/reference_task_qc.doctree new file mode 100644 index 000000000..4655ce4c1 Binary files /dev/null and b/.doctrees/reference_task_qc.doctree differ diff --git a/.doctrees/reference_write_your_own_task.doctree b/.doctrees/reference_write_your_own_task.doctree new file mode 100644 index 000000000..eb43afa08 Binary files /dev/null and b/.doctrees/reference_write_your_own_task.doctree differ diff --git a/.doctrees/usage.doctree b/.doctrees/usage.doctree new file mode 100644 index 000000000..8e0f6c900 Binary files /dev/null and b/.doctrees/usage.doctree differ diff --git a/.doctrees/usage_behavior.doctree b/.doctrees/usage_behavior.doctree new file mode 100644 index 000000000..b7b3f5552 Binary files /dev/null and b/.doctrees/usage_behavior.doctree differ diff --git a/.doctrees/usage_copy.doctree b/.doctrees/usage_copy.doctree new file mode 100644 index 000000000..c401566b2 Binary files /dev/null and b/.doctrees/usage_copy.doctree differ diff --git a/.doctrees/usage_neuropixel.doctree b/.doctrees/usage_neuropixel.doctree new file mode 100644 index 000000000..95e31bcec Binary files /dev/null and b/.doctrees/usage_neuropixel.doctree differ diff --git a/.doctrees/usage_video.doctree b/.doctrees/usage_video.doctree new file mode 100644 index 000000000..3841bea2e Binary files /dev/null and b/.doctrees/usage_video.doctree differ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/_images/amp2x15_labels.png b/_images/amp2x15_labels.png new file mode 100644 index 000000000..141638b49 Binary files /dev/null and b/_images/amp2x15_labels.png differ diff --git a/_images/gui.png b/_images/gui.png new file mode 100644 index 000000000..fc55586e8 Binary files /dev/null and b/_images/gui.png differ diff --git a/_images/hifi_labels.png b/_images/hifi_labels.png new file mode 100644 index 000000000..436428830 Binary files /dev/null and b/_images/hifi_labels.png differ diff --git a/_images/viewephys.png b/_images/viewephys.png new file mode 100644 index 000000000..2a86dc176 Binary files /dev/null and b/_images/viewephys.png differ diff --git a/_images/xonar_labels.png b/_images/xonar_labels.png new file mode 100644 index 000000000..d08692dd1 Binary files /dev/null and b/_images/xonar_labels.png differ diff --git a/_sources/changelog.rst.txt b/_sources/changelog.rst.txt new file mode 100644 index 000000000..9f448a2b9 --- /dev/null +++ b/_sources/changelog.rst.txt @@ -0,0 +1,2 @@ +.. include:: ../../CHANGELOG.md + :parser: myst_parser.sphinx_ diff --git a/_sources/faq.rst.txt b/_sources/faq.rst.txt new file mode 100644 index 000000000..480b2cf16 --- /dev/null +++ b/_sources/faq.rst.txt @@ -0,0 +1,121 @@ +************************** +Frequently Asked Questions +************************** + +Here we collect common issues and questions regarding IBLRIG. + +First Aid +========= + +If your rig is acting up: + +* Employ the **automated test-script** bundled with IBLRIG. This script helps identify common configuration issues. + Execute it using PowerShell: + + .. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + validate_iblrig + +* Check `the comprehensive user manual `__ ("Appendix 3" on GoogleDrive). + Verify if all connections are secure, and configurations align with the manual's guidelines. + +* Don't hesitate to **contact our developer team** for assistance. We're committed to getting your system back on track. + + +Bug Reports & Feature Requests +============================== + +IBLRIG remains in dynamic development. Your input is invaluable in shaping its direction. `Send us your +bug reports and feature-requests via GitHub `_ - we will do our best to help you. + + +Sound Issues +============ + +* Double-check all wiring for loose connections. + +* Is ``hardware_settings.yaml`` set up correctly? Valid options for sound ``OUTPUT`` are: + + - ``harp``, + - ``xonar``, or + - ``sysdefault``. + + Make sure that this value matches the actual soundcard used on your rig. + + +Screen Issues +============= + +General +^^^^^^^ + +* The ribbon cable attaching the screen to the driver board is notoriously finicky. If you are having brightness issues or do not have a signal, try gently repositioning this cable and ensure it is tightly seated in its connection. +* Screen and ribbon cable can be easily damaged. It is useful to have backup at hand. +* Screen flashing can occur if the power supply does not match the screen specifications. Use a 12V adapter with at least 1A. +* If the Bonsai display is appearing on the PC screen when a task starts, try unplugging the rig screen, rebooting and plugging the screen back in. Other variations of screen unplugging and rebooting may also work. + Also make sure, that the ``DISPLAY_IDX`` value in ``hardware_settings.yaml`` is set correctly. + +Defining Default Position & Size of Bonsai Visualizers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Is the preview window of the video recording showing on the iPad screen instead of the computer's main display during a +session? To redefine the default position and size of the Bonsai visualizer: + +#. Open the Bonsai executable distributed with IBLRIG: ``C:\iblrigv8\Bonsai\Bonsai.exe``. +#. Open the respective Bonsai workflow: + + .. code:: + + C:\iblrigv8\devices\camera_recordings\TrainingRig_SaveVideo_TrainingTasks.bonsai + +#. Start the workflow by clicking on the play-button. +#. Adjust the position and size of the windows as per your preference. +#. Stop the workflow. +#. Save the workflow. + + +Camera Issues +============= + +* If a camera is not detected by the computer or causes intermittent issues it might be an issue with the USB connection. + + * Ensure that the camera is connected to the computer on a USB3 port (usually indicated by a blue plastic tab in the port). + USB2 (black tabs) neither provides the necessary transfer rates nor sufficient current to power the camera. + * Use the `original USB3.1 cable `_ provided by FLIR. + It comes in 3 m or 5 m - stick with the shorter version if possible. + * Try to avoid USB extensions. + The original cable (see above) should be sufficiently long in most situations. + * Ideally, use one of the onboard USB3 ports of your computer facing to the back of the machine. + Front-facing ports may not be able to provide enough power. + * If you use a USB 3.1 Host Controller Card check if it requires additional powering through a SATA or Molex cable. + FLIR offers `a few models `_ that should work fine. + + +Frame2TTL +========= + +* Version 1 of Frame2TTL won't be detected after restarting the computer. + Unplugging and replugging the USB cable should make it responsive again. +* If IBLRIG complains about not receiving any TTL signals from Frame2TTL: + + * Ensure Frame2TTL's sensor is positioned over the bottom-right corner of the rig's screen. + Secure the sensor's cable to the screen mount with a zip-tie to prevent it from slipping off the screen. + Additionally, use a piece of electrical tape to hold the sensor in place. + + * Verify that the sensor is connected to Frame2TTL with the correct polarity + + * Version 1: GND = black cable, SIG = white cable + * Version 2 and 3: BLK = black cable, WHT = white cable + * Ensure that Frame2TTL's TTL Output is plugged into Bpod's TTL Input #1. + Note that versions 2 and 3 of Frame2TTL have a second BNC output labeled "analog" - this is *not* the TTL output. + * Recalibrate Frame2TTL using the calibration routine in IBLRIG's Tools menu and check for any errors. + +* If the above steps do not resolve the issue, try the following: + + #. Swap out the BNC cable between Frame2TTL and Bpod. + Use a single cable without any branches. + #. Connect an oscilloscope to the Bpod end of the cable and run a calibration. + Look for a voltage step in Frame2TTL's output when the calibration routine switches from dark to light. + #. If you *do* see the change in the TTL signal, the Bpod might be faulty. Try using a different Bpod unit. + #. If you do *not* see the voltage step, the Frame2TTL might be faulty. Try using a different Frame2TTL unit. diff --git a/_sources/hardware.rst.txt b/_sources/hardware.rst.txt new file mode 100644 index 000000000..d3f19db12 --- /dev/null +++ b/_sources/hardware.rst.txt @@ -0,0 +1,94 @@ +Hardware Guide +============== + + +Upgrading Xonar AE to Bpod HiFi Module +------------------------------------------------ + +.. note:: The following guide only concerns behavior rigs using `Asus Xonar AE` sound cards. + The `Harp` sound cards used in our Ephys and Mesoscope rigs work fine and do not require replacing! + +Background +"""""""""" + +In their original design, IBL’s behavioral training rigs relied on a consumer-grade sound-card - the `ASUS Xonar AE `_ - for delivering auditory cues to the subject. We have identified the Xonar AE as a weak point in the design of the training rig as this choice of hardware has several severe drawbacks: + +* Synchronization between individual components of the rig relies on TTL Signals, a standardized way of communicating between digital devices. + With the Xonar sound-card, we emulate TTL pulses on one of the soundcard’s analog audio outputs. + The resulting signal does not conform well to the TTL standard since (a) we cannot guarantee the required signal rise-times, and (b) pulse-amplitude depends on the computer’s audio volume and impedance settings. The effects are increased latencies and accidental misconfigurations. + The latter have the potential to cause synchronization issues and more problems further down the pipeline. +* The ASUS Xonar AE does not seem to be a particularly robust piece of equipment - we’ve experienced several catastrophic failures across our rigs at IBL. Replacement hardware is increasingly hard to come by as the Asus Xonar AE is not being produced anymore. +* The soundcard’s driver has been causing issues with specific Windows updates that require manual intervention / rollback of the respective updates. +* There is no Windows 11 specific driver available. + +For these reasons, we decided to replace the Xonar AE with the `Bpod HiFi Module HD `_ by Sanworks: +The HiFi Module is capable of delivering high fidelity sound stimuli at low latencies, supports proper TTL signaling as well as serial communication with the Bpod Finite State Machine and does not require any dedicated drivers. +The upgrade procedure is straightforward and should take no longer than 5-10 minutes. + +Requirements +"""""""""""" + +To replace your existing Xonar AE with the Bpod HiFi Module HD you will require the following: + +* 1x Bpod HiFi Module HD +* 1x Micro-USB to USB-A cable +* 1x Ethernet cable (RJ45) +* 1x RCA to 3.5 mm audio adapter +* 1x 3 mm flathead screwdriver + +.. warning:: Support for the Bpod HiFi Module was introduced with IBLRIG 8.16.0 and will not be backported to older version of IBLRIG. + Make sure to upgrade to the latest version of IBLRIG before continuing with this guide. + +Upgrade Procedure +""""""""""""""""" + +1. Use the 3 mm flathead screwdriver to unscrew the BNC to wire adapter from the amplifier board. + While the adapter itself is not needed anymore we will continue using the BNC cable. + Leave the other end of the BNC cable plugged into the Bpod as it is. + + .. figure:: img/amp2x15_labels.png + :width: 100% + :class: with-border + + Disconnect the BNC to wire adapter from the amplifier board. + +2. Unplug the 3.5 mm audio cable from the Xonar AE sound card on the backside of the rig's computer. + Leave the other end of the 3.5 mm audio cable connected to the amplifier board. + + .. figure:: img/xonar_labels.png + :width: 100% + :class: with-border + + Unplug the 3.5 mm audio cable from the Xonar AE sound card. + +3. Connect the Bpod HiFi Module as follows: + + * the BNC cable connects to TTL In 2 of the Bpod (cf. step 1), + * the 3.5 mm audio cable connects to the amplifier board via the RCA adapter (cf. step 2), + * the USB cable connects to the rig's computer + * the Ethernet cable connects to one of the Bpod's Module ports. + Warning: Bpod uses identical connectors for its Behavior ports - do not mix them up! + + .. figure:: img/hifi_labels.png + :width: 100% + :class: with-border + + The Bpod HiFi Modules and its connections. + +4. Open `C:/iblrigv8/settings/hardware_settings.yaml` in a text-editor. + Find the section `device_sound` and adapt it as follows: + + .. code-block:: yaml + + device_sound: + OUTPUT: hifi + COM_SOUND: COMx # replace with the HiFi Module's actual COM port! + AMP_TYPE: AMP2X15 + + .. tip:: + + Use Windows' device manager to identify the HiFi Module's COM port. + The device should show up in the section labelled "Ports (COM & LPT)" after plugging it in. + +5. Start IBLRIG and make sure that the hardware validation during start-up does not find any issues. + Finally, start a session and verify that you can hear the audio cues. \ No newline at end of file diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 000000000..680bc456c --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,18 @@ +IBLRIG documentation +==================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + installation + usage + reference + hardware + reference_developer_guide + faq + +.. toctree:: + :maxdepth: 1 + + changelog diff --git a/_sources/installation.rst.txt b/_sources/installation.rst.txt new file mode 100644 index 000000000..d1cf06890 --- /dev/null +++ b/_sources/installation.rst.txt @@ -0,0 +1,258 @@ +Installation guide +================== + +.. prerequisites:: + + * A computer running Windows 10 or 11, + * A working installation of `git for windows `_, and + * `Notepad++ `_ or some other decent text editor. + +.. tip:: + + iblrigv8 can be installed alongside older versions of iblrig without affecting the latter. + +.. tip:: + + If you believe this guide is incomplete or requires improvements, please don't hesitate to reach out and + :ref:`submit a bug report`. + + +Preparing Windows PowerShell +---------------------------- + +Open Windows PowerShell in administrator mode: + +* Click on the Windows Start button or press the Windows key on your keyboard. +* Type "PowerShell" into the search bar. +* You should see "Windows PowerShell" or "PowerShell" in the search results. +* Right-click on it. +* In the context menu that appears, select "Run as administrator." + +Now, run the following command at the prompt of Windows PowerShell: + +.. code-block:: powershell + + Set-ExecutionPolicy RemoteSigned -Force + +.. tip:: + + Keep the Administrator PowerShell open for the next step. + +.. admonition:: Background + :class: seealso + + In PowerShell, there are execution policies that determine the level of security for running scripts. The default execution + policy is often set to ``Restricted``, which means that scripts are not allowed to run. However, to install Python or run + certain scripts, you need to adjust the execution policy. By setting the execution policy to ``RemoteSigned``, you are + allowing the execution of locally created scripts without any digital signature while requiring that remotely downloaded + scripts (from the internet) must be digitally signed by a trusted source to run. This strikes a balance between security + and usability. + + +Installing MS Visual C++ Redistributable +---------------------------------------- + +With the Administrator PowerShell still open, run the following commands: + +.. code-block:: powershell + + New-Item -ItemType Directory -Force -Path C:\Temp + Invoke-WebRequest -Uri https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe -OutFile C:\Temp\vcredist_x64.exe + Start-Process -NoNewWindow -Wait -FilePath C:\Temp\vcredist_x64.exe -ArgumentList "/install", "/quiet", "/norestart" + Invoke-WebRequest -Uri https://aka.ms/vs/17/release/vc_redist.x64.exe -OutFile C:\Temp\vc_redist.x64.exe + Start-Process -NoNewWindow -Wait -FilePath C:\Temp\vc_redist.x64.exe -ArgumentList "/install", "/quiet", "/norestart" + +.. warning:: Make sure you exit the Administrator PowerShell before continuing with the next steps! + +.. admonition:: Background + :class: seealso + + These commands will create a temporary directory, download and silently install the Visual C++ Redistributable package for + 64-bit Windows systems. The installer is retrieved from a Microsoft server and executed with parameters to ensure a seamless + and unobtrusive installation process. + + +Installing Python 3.10 +---------------------- + +Open a `new` Windows Powershell prompt (no administrator mode) and run the following: + +.. code-block:: powershell + + New-Item -ItemType Directory -Force -Path C:\Temp + Invoke-WebRequest -Uri https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe -OutFile C:\Temp\python-3.10.11-amd64.exe + Start-Process -NoNewWindow -Wait -FilePath C:\Temp\python-3.10.11-amd64.exe -ArgumentList "/passive", "InstallAllUsers=0", "Include_launcher=0", "Include_test=0" + +Check that everything worked by running the following command: + +.. code-block:: powershell + + &$env:UserProfile\AppData\Local\Programs\Python\Python310\python.exe --version + +The command should return ``Python 3.10.11`` + + +.. admonition:: Background + :class: seealso + + These commands will create a temporary directory, download the Python installer from a specific URL, and then execute the + installer with specific installation options, all in a controlled and automated manner. + + +Installing iblrigv8 +------------------- + +1. From the Powershell command line, clone the `iblrigv8` branch of iblrig to ``C:\iblrigv8``: + + .. code-block:: powershell + + git clone -b iblrigv8 https://github.com/int-brain-lab/iblrig.git C:\iblrigv8 + + +2. Install a new virtual environment and update pip: + + .. code-block:: powershell + + &$env:UserProfile\AppData\Local\Programs\Python\Python310\python.exe -m venv C:\iblrigv8\venv + C:\iblrigv8\venv\scripts\python.exe -m pip install --upgrade pip wheel + + +3. Install iblrig in editable mode: + + .. code-block:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + cd C:\iblrigv8 + pip install -e . + + +4. Install Spinnaker SDK and PySpin: + + .. code-block:: powershell + + install_spinnaker + install_pyspin + + +5. Install Bonsai in portable mode: + + .. code-block:: powershell + + cd C:\iblrigv8\Bonsai + powershell.exe .\install.ps1 + cd .. + + +6. Install additional tasks and extractors for personal projects (optional): + + .. code-block:: powershell + + git clone https://github.com/int-brain-lab/project_extraction.git C:\project_extraction + cd C:\project_extraction + pip install -e . + + +7. Continue with :ref:`the next section`. + + +Configuration Instructions +-------------------------- + +Rig Configuration Files +~~~~~~~~~~~~~~~~~~~~~~~ + +Copy the template settings files: + +.. code-block:: + + cd C:\iblrigv8\settings + cp hardware_settings_template.yaml hardware_settings.yaml + cp iblrig_settings_template.yaml iblrig_settings.yaml + explorer C:\iblrigv8\settings + + +Update the two settings files using a text-editor: + +* ``iblrig_settings.yaml`` +* ``hardware_settings.yaml`` + +If the computer has been used with IBLRIG version 7 or earlier, the correct values can likely be found in ``C:\iblrig_params\ +.iblrig_params.json``. + + +Setting up ONE +~~~~~~~~~~~~~~ + + +Setup ONE to connect to https://alyx.internationalbrainlab.org, you will need your Alyx username and password. + +See instructions for that here: https://int-brain-lab.github.io/iblenv/notebooks_external/one_quickstart.html + + +.. exercise:: Make sure you can connect to Alyx ! + + Open a Python shell in the environment and connect to Alyx (you may have to setup ONE) + + .. code-block:: + + C:\iblrigv8\venv\scripts\Activate.ps1 + ipython + + Then at the IPython prompt + + .. code-block:: python + + from one.api import ONE + one = ONE(username='your_username', password='your_password', base_url='https://alyx.internationalbrainlab.org') + + +.. exercise:: You can check that everything went fine by running the test suite: + + .. code-block:: powershell + + cd C:\iblrigv8 + python -m unittest discover + + The tests should pass to completion after around 40 seconds + + +Updating iblrigv8 +----------------- + +To update iblrigv8 to the newest version: + +.. code-block:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + cd C:\iblrigv8 + git pull + pip install --upgrade -e . + + +To update the additional tasks and extractors (see :ref:`Installing iblrigv8`, point 5): + +.. code-block:: powershell + + cd C:\project_extraction + git pull + + +Switch to specific iblrig version +--------------------------------- +.. warning:: Downgrading is not recommended and may not work as some releases break compatibility with earlier versions. + +First fetch all available version tags and list them: + +.. code-block:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + cd C:\iblrigv8 + git fetch --all --tags --prune + git tag --list '8.*' + +Then switch to the desired version, for example `8.15.5`: + +.. code-block:: powershell + + git checkout tag/8.15.5 + pip install --upgrade -e . diff --git a/_sources/reference.rst.txt b/_sources/reference.rst.txt new file mode 100644 index 000000000..64ed18a02 --- /dev/null +++ b/_sources/reference.rst.txt @@ -0,0 +1,8 @@ +************************************ +Reference +************************************ + +.. include:: reference_description_file.rst +.. include:: reference_task_qc.rst +.. include:: reference_write_your_own_task.rst +#.. include:: reference_developer_guide.rst diff --git a/_sources/reference_description_file.rst.txt b/_sources/reference_description_file.rst.txt new file mode 100644 index 000000000..121150739 --- /dev/null +++ b/_sources/reference_description_file.rst.txt @@ -0,0 +1,215 @@ +Describing an Experiment +======================== + +Experiment description file +--------------------------- + +All experiments are described by a file with the name +``_ibl_experiment.description.yaml``. This description file contains +details about the experiment such as, information about the devices used +to collect data, or the behavior tasks run during the experiment. The +content of this file is used to copy data from the acquisition computer +to the lab server and also determines the task pipeline that will be +used to extract the data on the lab servers. It’s accuracy in fully +describing the experiment is, therefore, very important! + +Here is an example of a complete experiment description file for a +mesoscope experiment running two consecutive tasks, +``biasedChoiceWorld`` followed by ``passiveChoiceWorld``. + +.. code:: yaml + + devices: + mesoscope: + mesoscope: + collection: raw_imaging_data* + sync_label: chrono + cameras: + belly: + collection: raw_video_data + sync_label: audio + width: 640 + height: 512 + fps: 30 + left: + collection: raw_video_data + sync_label: audio + right: + collection: raw_video_data + sync_label: audio + procedures: + - Imaging + projects: + - ibl_mesoscope_active + sync: + nidq: + acquisition_software: timeline + collection: raw_sync_data + extension: npy + tasks: + - _biasedChoiceWorld: + collection: raw_task_data_00 + sync_label: bpod + extractors: [TrialRegisterRaw, ChoiceWorldTrialsTimeline, TrainingStatus] + - passiveChoiceWorld: + collection: raw_task_data_01 + sync_label: bpod + extractors: [PassiveRegisterRaw, PassiveTaskTimeline] + version: 1.0.0 + +Breaking down the components of an experiment description file +-------------------------------------------------------------- + +Devices +~~~~~~~ + +The devices section in the experiment description file lists the set of +devices from which data was collection in the experiment. Supported +devices are Cameras, Microphone, Mesoscope, Neuropixel, Photometry and +Widefield. + +The convention for this section is to have the device name followed by a +list of sub-devices, e.g. + +.. code:: yaml + + devices: + cameras: + belly: + collection: raw_video_data + sync_label: audio + width: 640 + height: 512 + fps: 30 + left: + collection: raw_video_data + sync_label: audio + right: + collection: raw_video_data + sync_label: audio + +In the above example, ``cameras`` is the device and the sub-devices are +``belly``, ``left`` and ``right``. + +If there are no sub-devices, the sub-device is given the same name as +the device, e.g. + +.. code:: yaml + + devices: + mesoscope: + mesoscope: + collection: raw_imaging_data* + sync_label: chrono + +Each sub-device must have at least the following two keys - +**collection** - the folder containing the data - **sync_label** - the +name of the common ttl pulses in the channel map used to sync the +timestamps + +Additional keys can also be specified for specific extractors, e.g. for +the belly camera the camera metadata passed into the camera extractor +task is defined in this file. + +Procedures +~~~~~~~~~~ + +The procedures section lists the set of procedures that apply to this +experiment. The list of possible procedures can be found +`here `__. + +As many procedure that apply to the experiment can be added e.g. + +.. code:: yaml + + procedures: + - Fiber photometry + - Optical stimulation + - Ephys recording with acute probe(s) + +Projects +~~~~~~~~ + +The projects section lists the set of projects that apply to this +experiment. The list of possible projects can be found +`here `__. + +As many projects that apply to the experiment can be added e.g. + +:: + + projects: + - ibl_neuropixel_brainwide_01 + - carandiniharris_midbrain_ibl + +Sync +~~~~ + +The sync section contains information about the device used to collect +the syncing data and the format of the data. Supported sync devices are +bpod, nidq, tdms, timeline. Only **one** sync device can be specified +per experiment description file and act as the main clock to which other +timeseries are synced. + +An example of an experiment run with bpod as the main syncing device is, + +.. code:: yaml + + sync: + bpod: + collection: raw_behavior_data + extension: bin + +Another example for spikeglx electrophysiology recordings with +Neuropixel 1B probes use the nidq as main synchronisation. + +.. code:: yaml + + sync: + nidq: + collection: raw_ephys_data + extension: bin + acquisition_software: spikeglx + +Each sync device must have at least the following two keys - +**collection** - the folder containing the data - **extension** - the +file extension of the sync data + +Optional keys include, for example ``acquisition_software``, the +software used to acquire the sync pulses + +Tasks +~~~~~ + +The tasks section contains a list of the behavioral protocols run during +the experiment. The name of the protocol must be given in the list e.g. + +.. code:: yaml + + tasks: + - _biasedChoiceWorld: + collection: raw_task_data_00 + sync_label: bpod + extractors: [TrialRegisterRaw, ChoiceWorldTrialsTimeline, TrainingStatus] + - passiveChoiceWorld: + collection: raw_task_data_01 + sync_label: bpod + extractors: [PassiveRegisterRaw, PassiveTaskTimeline] + +Each task must have at least the following two keys - **collection** - +the folder containing the data - **sync_label** - the name of the common +ttl pulses in the channel map used to sync the timestamps + +The ``collection`` must be unique for each task. i.e. Data from two +tasks cannot be stored in the same folder. + +If the Tasks used to extract the data are not the default tasks, the +extractors to use must be passed in as an additional key. The order of +the extractors defines their parent child relationship in the task +architecture. + +Version +~~~~~~~ + +The version section gives version number of the experiment description +file diff --git a/_sources/reference_developer_guide.rst.txt b/_sources/reference_developer_guide.rst.txt new file mode 100644 index 000000000..ee365eb55 --- /dev/null +++ b/_sources/reference_developer_guide.rst.txt @@ -0,0 +1,129 @@ +Developer Guide +=============== + + +Versioning Scheme +----------------- + +IBLRIG v8 uses `Semantic Versioning 2.0.0 `_. +Its version string (currently "|version|") is a combination of three fields, separated by dots: + +.. centered:: ``MAJOR`` . ``MINOR`` . ``PATCH`` + +* The ``MAJOR`` field is only incremented for breaking changes, i.e., changes that are not backward compatible with previous changes. + Releases of IBLRIG v8, for instance, are generally incompatible with IBLRIG v7. +* The ``MINOR`` field will be incremented upon adding new, backwards compatible features. +* The ``PATCH`` field will be incremented with each new, backwards compatible bugfix release that does not implement a new feature. + +On the developer side, these 3 fields are manually controlled by, both + + 1. adjusting the variable ``__version__`` in ``iblrig/__init__.py``, and + 2. adding the corresponding version string to a commit as a `git tag `_, + for instance: + + .. code-block:: console + + git tag 8.8.4 + git push origin --tags + +The version string displayed by IBLRIG *may* include additional fields, such as in "|version|.post3+dirty". +Here, + +* ``post3`` indicates the third unversioned commit after the latest versioned release, and +* ``dirty`` indicates the presence of uncommited changes in your local repository of IBLRIG. + +Both of these fields are inferred by means of git describe and do not require manual interaction from the developer. + + +Installing Developer Dependencies +--------------------------------- + +To install additional dependencies needed for working on IBLRIG's code-base, run the following within the venv: + +.. code-block:: console + + pip install -U -e .[DEV] + + +Running Unit Tests Locally +-------------------------- + +To run unit tests locally, run the following within IBLRIG's venv: + +.. code-block:: console + + pytest + +This will also generate a coverage report which can be found in the ``htmlcov`` directory. + + +Linting & Formatting +-------------------- + +To lint your code, run the following within IBLRIG's venv: + +.. code-block:: console + + ruff check . + +Adding the commandline flag ``--fix`` will automatically fix issues that are deemed safe to handle: + +.. code-block:: console + + ruff check . --fix + +To *check* if your code conforms to the `Black code style `_, run: + +.. code-block:: console + + ruff format . --check + +To reformat your code according to the `Black code style `_, run: + +.. code-block:: console + + ruff format . + +Refer to `Ruff Formater's documentation `_ for further details. + + +Release Checklist +----------------- + +1) update CHANGELOG.md including changes from the last tag +2) Pull request to ``iblrigv8dev`` +3) Check CI and eventually wet lab test +4) Pull request to ``iblrigv8`` +5) Merge PR +6) git tag the release in accordance to the version number below (after merge!) + + +Building the documentation +-------------------------- + +.. code-block:: console + + # make sure pre-requisites are installed + pip install --upgrade -e .[DEV] + # create the static directory + rm -rf ./docs/build + mkdir -p ./docs/build/html/_static + # unit tests generate task diagrams + python -m unittest discover ./iblrig/test + # generate class diagrams + pyreverse -o png -m y --ignore iblrig.test -A --output-directory ./docs/build/html/_static ./iblrig_tasks + # build and serve the docs locally + sphinx-autobuild ./docs/source ./docs/build/html/ + +Contribute to the documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To write the documentation: + +* Write the documentation in the ``iblrig/docs/source`` folder +* If you are writing in a new file, add it to the ``index.rst`` so it appears in the table of content +* Push all your changes to the ``iblrigv8dev`` branch ; if this branch does not exist, create it first + +To release the documentation onto the `website `_: + +* Wait for the next release, or +* Manually trigger the GitHub action by clicking "Run Workflow" (select ``master``) `here `_ diff --git a/_sources/reference_task_qc.rst.txt b/_sources/reference_task_qc.rst.txt new file mode 100644 index 000000000..ef90d8084 --- /dev/null +++ b/_sources/reference_task_qc.rst.txt @@ -0,0 +1,120 @@ +Quality check the task post-usage +================================= + +Once a session is acquired, you can verify whether the trials data is extracted properly and that the sequence of events matches the expected logic of +the task. + +Metrics definitions +------------------- +All the metrics computed as part of the Task logic integrity QC (Task QC) are implemented in +`ibllib `__. +When run at a behavior rig, they are computed using the Bpod data, without alignment to another DAQ's clock. + +.. tip:: + + The Task QC metrics definitions can be found in this `documentation page `__. + See `this page `__ on how to write QC checks for a custom task protocol. + + +Some are essential, i.e. if they fail you should immediately take action and verify your rig, +and some are not as critical. + +Essential taskQCs: + +* check_audio_pre_trial +* check_correct_trial_event_sequence +* check_error_trial_event_sequence +* check_n_trial_events +* check_response_feedback_delays +* check_reward_volume_set +* check_reward_volumes +* check_stimOn_goCue_delays +* check_stimulus_move_before_goCue +* check_wheel_move_before_feedback +* check_wheel_freeze_during_quiescence + +Non essential taskQCs: + +* check_stimOff_itiIn_delays +* check_positive_feedback_stimOff_delays +* check_negative_feedback_stimOff_delays +* check_wheel_move_during_closed_loop +* check_response_stimFreeze_delays +* check_detected_wheel_moves +* check_trial_length +* check_goCue_delays +* check_errorCue_delays +* check_stimOn_delays +* check_stimOff_delays +* check_iti_delays +* check_stimFreeze_delays +* check_wheel_integrity + +.. tip:: + + The value returned by each metric is the proportion of trial that fail to pass the given test. + For example, if the value returned by ``check_errorCue_delays`` is 0.92, it means 8% of the trials failed this test. + +Quantifying the task QC outcome at the session level +---------------------------------------------------- + +The criteria for whether a session passes the Task QC is: + +* ``NOT_SET``: default value (= not run yet) +* ``FAIL``: if at least one metric is < 95% +* ``WARNING``: if all metrics are >=95% , and at least one metric is <99 % +* ``PASS``: if all metrics are >= 99% + +This aggregation is done on all metrics, regardless if they are essential or not. + +The criteria is defined at +`this code line `__ + +How to check the task QC outcome +-------------------------------- + +Immediately after acquiring a session +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +At the behaviour PC, before the data have been copied, use the `task_qc` command with the session path: + +.. code-block:: shell-session + + task_qc C:\iblrigv8_data\Subjects\KS022\2019-12-10\001 --local + +More information can be found `here `__, or by running `task_qc --help`. + +Once the session is registered on Alyx +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. **Check on the Alyx webpage** + + From the `session overview page on Alyx `__, + find your session click on ``See more session info``. + The session QC is displayed in one of the right panels. + + To get more information regarding which test pass or fail (contributing to this overall session QC), + you can click on the ``QC`` menu on the left. Bar-diagrams will appear, with essentials QCs on the + left, colored in green if passing. + + .. tip:: + You can hover over the bars with your mouse to easily know the name of the corresponding metric. + This is useful if the value of the metric is ``0``. + + .. warning:: + If an :ref:`essential metric` fails, run the Task QC Viewer to investigate why. + +2. **Run the taskQC Viewer to investigate** + + The application `Task QC Viewer `__ + enables to visualise the data streams of problematic trials. + + .. tip:: + Unlike when run at the behaviour PC, after registration the QC is run on the final time-aligned data (if applicable). + + + .. exercise:: Run the task QC metrics and viewer + + Select the ``eid`` for your session to inspect, and run the following within the iblrig env: + + .. code-block:: shell-session + + task_qc baecbddc-2b86-4eaf-a6f2-b30923225609 diff --git a/_sources/reference_write_your_own_task.rst.txt b/_sources/reference_write_your_own_task.rst.txt new file mode 100644 index 000000000..94871fc2b --- /dev/null +++ b/_sources/reference_write_your_own_task.rst.txt @@ -0,0 +1,130 @@ +Guide to develop a custom task +============================== + +iblrigv8 design: inheritance +---------------------------- + +During the lifetime of the IBL project, we realized that multiple task variants combine with multiple hardware configurations and acquisition modalities, leading to a combinatorial explosion of possible tasks and related hardware. + +This left us with the only option of developing a flexible task framework through hierarchical inheritance. + +All tasks inherit from the ``iblrig.base_tasks.BaseSession`` class, which provides the following functionalities: + - read hardware parameters and rig parameters + - optionally interfaces with the `Alyx experimental database `_ + - creates the folder structure for the session + - writes the task and rig parameters, log, and :doc:`acquisition description files <../description_file>` + +Additionally the ``iblrig.base_tasks`` module provides "hardware mixins". Those are classes that provide hardware-specific functionalities, such as connecting to a Bpod or a rotary encoder. They are composed with the ``BaseSession`` class to create a task. + +.. warning:: + + This sounds complicated ? It is ! + Forecasting all possible tasks and hardware add-ons and modification is fool's errand, however we can go through specific examples of task implementations. + + +Guide to Creating Your Own Task +------------------------------- + +What Happens When Running an IBL Task? + +1. The task constructor is invoked, executing the following steps: + + - Reading of settings: hardware and IBLRIG configurations. + - Reading of task parameters. + - Instantiation of hardware mixins. + +2. The task initiates the ``run()`` method. Prior to execution, this + method: + + - Launches the hardware modules. + - Establishes a session folder. + - Saves the parameters to disk. + +3. The experiment unfolds: the ``run()`` method triggers the ``_run()`` + method within the child class: + + - Typically, this involves a loop that generates a Bpod state + machine for each trial and runs it. + +4. Upon SIGINT or when the maximum trial count is reached, the + experiment concludes. The end of the ``run()`` method includes: + + - Saving the final parameter file. + - Recording administered water and session performance on Alyx. + - Halting the mixins. + - Initiating local server transfer. + +Examples +-------- + +.. admonition:: Where to write your task + :class: seealso + + After the :doc:`installation of iblrig <../installation>` the `project extraction `_ repository is located at the root of the C: drive. + New tasks should be added to the ``C:\project_extraction\iblrig_custom_tasks`` folder to be made visible by the `iblrig` GUI. + We use a convention that the task name starts with the author identifier, followed by an underscore, followed by the task name, such as `olivier_awesomeChoiceWorld`. + + + olivier_awesomeChoiceWorld + - __init__.py + - task.py + - README.md + - task_parameters.yaml + - test_olivier_awesomeChoiceWorld.py + + +Example 1: variation on biased choice world +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We will create a a choice world task that modifies a the quiescence period duration random draw policy. +In the `task.py` file, the first step is to create a new task class that inherits from the ``BiasedChoiceWorldSession`` class. + +Then we want to make sure that the task bears a distinctive protocol name, `_iblrig_tasks_imagingChoiceWorld`. +We also create the command line entry point for the task that will be used by the `iblrig` GUI. + +Also, in this case we can leverage the IBL infrastructure to perform extraction of the trials using existing extractors `extractor_tasks = ['TrialRegisterRaw', 'ChoiceWorldTrials']` + + .. code-block:: python + + import iblrig.misc + from iblrig.base_choice_world import BiasedChoiceWorldSession + + + class Session(BiasedChoiceWorldSession): + protocol_name = "_iblrig_tasks_imagingChoiceWorld" + + def __init__(self, *args, **kwargs): + self.extractor_tasks = ['TrialRegisterRaw', 'ChoiceWorldTrials'] + super().__init__(*args, **kwargs) + + if __name__ == "__main__": # pragma: no cover + kwargs = iblrig.misc.get_task_arguments(parents=[Session.extra_parser()]) + sess = Session(**kwargs) + sess.run() + + +In this case the parent class `BiasedChoiceWorldSession` has a method that draws the quiescence period. We are going to overload this method to add our own policy. This means the parent method will be fully replaced by our implementation. +The class now looks like this: + + .. code-block:: python + + class Session(BiasedChoiceWorldSession): + protocol_name = "_iblrig_tasks_imagingChoiceWorld" + + def draw_quiescent_period(self): + """ + For this task we double the quiescence period texp draw and remove the absolute + offset of 200ms. The resulting is a truncated exp distribution between 400ms and 1 sec + """ + return iblrig.misc.texp(factor=0.35 * 2, min_=0.2 * 2, max_=0.5 * 2) + +Et voilà, in a few lines, we re-used the whole biased choice world implementation to add a custom parameter. This is the most trivial and easy example. +The full code is available `here `_. + + +Example 2: re-writing a state-machine for a biased choice world task +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In some instances changes in the task logic require to go deeper and re-write the sequence of task events. In bpod parlance, we are talking about rewritng the state-machine code. + +Coming, for now here is an example of such a `task `_. diff --git a/_sources/usage.rst.txt b/_sources/usage.rst.txt new file mode 100644 index 000000000..344039fef --- /dev/null +++ b/_sources/usage.rst.txt @@ -0,0 +1,8 @@ +************************************ +Using IBLRIG v8 +************************************ + +.. include:: usage_behavior.rst +.. include:: usage_copy.rst +.. include:: usage_video.rst +.. include:: usage_neuropixel.rst diff --git a/_sources/usage_behavior.rst.txt b/_sources/usage_behavior.rst.txt new file mode 100644 index 000000000..5ff37c922 --- /dev/null +++ b/_sources/usage_behavior.rst.txt @@ -0,0 +1,111 @@ +Running a behaviour experiment +============================== + +IBLRIG v8 provides users with two distinct interfaces: a command line interface (CLI) and a graphical user interface (GUI). +The CLI encompasses the complete functionality of IBLRIG, upon which the GUI is constructed to enhance user-friendliness. +All tasks achievable through the GUI are equally achievable through the CLI. + + +The Graphical User Interface +---------------------------- + +To initiate a task through the graphical user interface, open a Windows PowerShell and enter: + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + iblrig + +These commands activate the necessary environment and launch the IBL +Rig Wizard GUI window, as shown below: + +.. figure:: gui.png + :alt: A screenshot of IBL Rig Wizard + :align: center + + A screenshot of IBL Rig Wizard + + +Starting a Task +~~~~~~~~~~~~~~~ + +1. Enter your Alyx username, then click on the *Connect* button. This + action will automatically populate the GUI fields with information + pertinent to your lab. + +2. Select the desired values from the provided options. Utilize the + *Filter* field to swiftly narrow down the list of displayed subjects. + Note that selections for *Project* and *Procedure* are mandatory. + +3. Click the *Start* button to initiate the task. + + +Supplementary Controls +~~~~~~~~~~~~~~~~~~~~~~ + +- If you check the *Append* option before clicking *Start*, the task + you initiate will be linked to the preceding task, creating a + sequence of connected tasks. + +- The *Flush* button serves to toggle the valve for cleaning purposes. + +.. note:: + IBLRIG's Graphical User Interface is still work-in-progress. If you have any suggestions to make the GUI + more usable, please add an `issue on GitHub `_ or approach the dev-team on Slack! + We are happy to discuss possible changes with you! + + +Interfacing with Alyx +--------------------- + +Although this is not mandatory, the IBLRIG GUI is designed to interface with `Alyx `_, the International Brain Laboratory's database. +This feature allows users to access their subjects and projects directly from the GUI, without the need to manually enter this information. + +To enable this feature, you must have an Alyx account and have configured your database URL and credentials as mentioned :doc:`installation`. + +- The *subjects* available are the set of alyx subjects that are alive, not stock, and belong to the lab defined in the `iblrig_settings.py` file. +- The *projects* available are the set of projects of which the current user is a participant. Login to Alyx > Subjects > Projects to check your projects. + + +The Command Line Interface +-------------------------- + +To use the command line interface, open a terminal and activate the +environment: + +.. code:: powershell + + cd C:\iblrigv8\ + venv\scripts\Activate.ps1 + +Running a single task +~~~~~~~~~~~~~~~~~~~~~ + +To run a single task, execute the following command: + +.. code:: powershell + + python .\iblrig_tasks\_iblrig_tasks_trainingChoiceWorld\task.py --subject algernon --user john.doe + +Chaining several tasks together +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To chain several tasks together, use the ``--append`` flag. For +instance, to run a passive task after an ephys task: + +1. Run the ephys task + + .. code:: powershell + + .\iblrig_tasks\_iblrig_tasks_ephysChoiceWorld\task.py --subject algernon + +2. Run the passive task with the ``--append``\ flag: + + .. code:: powershell + + .\iblrig_tasks\_iblrig_tasks_passiveChoiceWorld\task.py --subject algernon --append + +Flushing the valve +~~~~~~~~~~~~~~~~~~ + +To flush valve 1 of the Bpod, type ``flush`` and confirm with ENTER. Press ENTER again to close the valve. diff --git a/_sources/usage_copy.rst.txt b/_sources/usage_copy.rst.txt new file mode 100644 index 000000000..66d75ade8 --- /dev/null +++ b/_sources/usage_copy.rst.txt @@ -0,0 +1,177 @@ + +Copy commands +============= + +Usage +----- + +To initiate the data transfer from the local server to the remote +server, open a terminal and type. + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + transfer_data --tag behavior + +The transfer local and remote directories are set in the +``iblrig/settings/iblrig_settings.py`` file. + +To copy data at another acquisition PC, such as video and ephys, use the relevant tag, e.g. + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + transfer_data --tag video + +NB: By default the local data that was copied over 2 weeks ago will be automatically removed. To +avoid this set the cleanup-weeks argument to -1: + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + transfer_data behavior --cleanup-weeks -1 + +See the 'Clean-up local data' section on how to remove data without calling the copy script. + +To view the copy status of your local sessions without actually copying, use the 'dry' argument: + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + transfer_data behavior --dry + +For more information on the tranfer_data arguments, use the help flag: + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + transfer_data --help + + +Clean-up local data +------------------- + +To remove sessions fully copied to the server and older than 2 weeks, +open a terminal and type: + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + remove-old-sessions + +Note: the server needs to be up and running or the sessions won’t be +verified as copied. + + +Behind the Copy Scripts +----------------------- + +Workflow +~~~~~~~~ + +1. **Initial Stub Creation:** At the start of acquisition, an incomplete + experiment description file - a *‘stub’* - is saved to the session + on, both, the local PC and the lab server in a subfolder called + ``_devices``. The filename of the stub includes the PC’s identifier, + allowing the copy script to identify its source. + +2. **Executing the Copy Script:** The copy script is executed on each + acquisition PC independently and in no particular order. + +3. **Navigating Local Session Data:** The script systematically + navigates through local session folders (or optionally a separate + ``transfers`` folder) that contain ``experiment.description`` stubs. + +4. **Skipping Transferred Sessions:** The script ignores session folders + containing a file named ``transferred.flag`` (see 7). + +5. **Copying Collections:** For each session, the script reads the + respective stub and uses ``rsync`` to copy each ``collection``. + Subfolders not specified under a ``collection`` key are omitted from + copying. + +6. **Removing Remote Stubs:** Upon successful copying, the remote stub + file is merged with the remote ``experiment.description`` file (or + copied over if one doesn’t exist already). The remote stub file is + then deleted. + +7. **Confirming Transfer Locally:** A ``transferred.flag`` file is + created in the local session folder to confirm the transfer’s + success. + +8. **Completion and Cleanup:** Once no more remote stub files exist + for a given session, the empty ``_devices`` subfolder is removed. + Additionally, a ‘raw_session.flag’ file is created in the remote session folder, + indicating the successful transfer of all files. + +Example of workflow +~~~~~~~~~~~~~~~~~~~ + +Example of three sessions each in a different copy state: + +* The State on the Remote Lab Server + :: + + lab server/ + └── subject/ + └── 2020-01-01/ + ├── 001/ + │ └── _devices/ + │ ├── 2020-01-01_1_subject@taskPC.yaml + │ └── 2020-01-01_1_subject@ephysPC.yaml + ├── 002/ + │ ├── _ibl_experiment.description.yaml + │ ├── raw_task_data_00/ + │ └── _devices/ + │ └── 2020-01-01_1_subject@ephysPC.yaml + └── 003/ + ├── raw_task_data_00/ + ├── raw_ephys_data/ + ├── _ibl_experiment.description.yaml + └── raw_session.flag + + +* The State on the Local Task Acquisition PC + :: + + acquisition computer (taskPC)/ + └── subject/ + └── 2020-01-01/ + ├── 001/ + │ ├── raw_task_data_00/ + │ └── _ibl_experiment.description_taskPC.yaml + ├── 002/ + │ ├── raw_task_data_00/ + │ ├── _ibl_experiment.description_taskPC.yaml + │ └── transferred.flag + └── 003/ + ├── raw_task_data_00/ + ├── folder_not_in_desc_file/ + ├── _ibl_experiment.description_taskPC.yaml + └── transferred.flag + + +* The State on the Local Ephys Acquisition PC + :: + + acquisition computer (ephysPC)/ + └── subject/ + └── 2020-01-01/ + ├── 001/ + │ ├── raw_ephys_data/ + │ └── _ibl_experiment.description_ephysPC.yaml + ├── 002/ + │ ├── raw_ephys_data/ + │ ├── _ibl_experiment.description_ephysPC.yaml + └── 003/ + ├── raw_ephys_data/ + ├── folder_not_in_desc_file/ + ├── _ibl_experiment.description_ephysPC.yaml + └── transferred.flag + +With the lab server and acquisition pcs in the states above, the +sessions are in the following states + +* ``subject/2020-01-01/001`` no data have been copied. +* ``subject/2020-01-01/002`` data from *taskPC* have been copied, data from *ephysPC* remains to be copied. +* ``subject/2020-01-01/003`` data copied from all acquisition PCs. diff --git a/_sources/usage_neuropixel.rst.txt b/_sources/usage_neuropixel.rst.txt new file mode 100644 index 000000000..f315d3c84 --- /dev/null +++ b/_sources/usage_neuropixel.rst.txt @@ -0,0 +1,66 @@ +Neuropixel recording with iblrigv8 +================================== + +This document describes how to use the iblrigv8 software to record from the Neuropixel computer. + +Setup +----- + +Just make sure iblrigv8 is installed according to the instructions and that the iblrig_settings.py +file is configured with the local folder and remote folder for the data transfer. + +To get access to the viewephys visualizer: + +.. code:: powershell + + cd C:\iblrigv8\ + venv\scripts\Activate.ps1 + pip install viewephys + +Starting a task +--------------- + +Below shows how to start the electrophysiology for the subject 'example' with 2 probes: + +.. code:: powershell + + cd C:\iblrigv8\ + venv\scripts\Activate.ps1 + start_ephys_session example 2 + + +Copy command +------------ + +Usage +~~~~~ + +To initiate the data transfer from the local server to the remote server, open a terminal and type. + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + transfer_data --tag ephys + +The transfer local and remote directories are set in the +``iblrig/settings/iblrig_settings.py`` file. + + +Look at the raw data +-------------------- + +This will launch the viewephys GUI, you can then use file -> open and navigate +to open the raw data file you wish to display. + +.. code:: powershell + + cd C:\iblrigv8\ + venv\scripts\Activate.ps1 + viewephys + +.. image:: img/viewephys.png + :width: 800 + :alt: Alternative text + + +More information on the viewephys package can be found at: https://github.com/int-brain-lab/viewephys \ No newline at end of file diff --git a/_sources/usage_video.rst.txt b/_sources/usage_video.rst.txt new file mode 100644 index 000000000..c5160e286 --- /dev/null +++ b/_sources/usage_video.rst.txt @@ -0,0 +1,81 @@ +Video acquisition computer +========================== + +Video can be run on a separate computer, which is recommended when recording multiple cameras. + + +Setup +----- + +Installing drivers +~~~~~~~~~~~~~~~~~~ + +Both spinnaker and pyspin must be installed before running an experiment: + +.. code:: powershell + + cd C:\iblrigv8\ + venv\scripts\Activate.ps1 + install_spinnaker + install_pyspin + + +Settings config +~~~~~~~~~~~~~~~ + +The camera acquisition is configured by parameters in the 'device_cameras' key of the `hardware_settings.yaml` file. +Below is an overview of the parameters: + +.. code:: yaml + + device_cameras: + # The name of the configuration. This is passed to the CLI. + default: + # This is required: the Bonsai workflows to be called by the CLI script. + BONSAI_WORKFLOW: + # Optional setup (e.g. alignment) workflow + setup: devices/camera_setup/EphysRig_SetupCameras.bonsai + # Required workflow to be called when the experiment starts + recording: devices/camera_recordings/TrainingRig_SaveVideo_TrainingTasks.bonsai + # Camera #1 name + left: + # Required camera device index (assigned in driver software) + INDEX: 1 + # Optional expected frame height. Actual resolution should be set in the driver software. + HEIGHT: 1024 + # Optional expected frame width. This is simply used in QC. + WIDTH: 1280 + # Optional expected frame rate (Hz). This is simply used in QC. + FPS: 30 + +Multiple configurations can be added, e.g. 'default', 'training', 'ephys', etc. and within each, multiple cameras +can be added, e.g. 'left', 'right', 'body', etc. Each configuration requires a `BONSAI_WORKFLOW: recording` key; +each camera requires an `INDEX` key. + + +Starting a task +--------------- + +Below shows how to start the cameras for the subject 'example' with configuration 'default': + +.. code:: powershell + + cd C:\iblrigv8\ + venv\scripts\Activate.ps1 + start_video_session example default + +Copy command +------------ + +Usage +~~~~~ + +To initiate the data transfer from the local server to the remote server, open a terminal and type. + +.. code:: powershell + + C:\iblrigv8\venv\scripts\Activate.ps1 + transfer_data --tag video + +The transfer local and remote directories are set in the +``iblrig/settings/iblrig_settings.py`` file. diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 000000000..81415803e --- /dev/null +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 000000000..f316efcb4 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/check-solid.svg b/_static/check-solid.svg new file mode 100644 index 000000000..92fad4b5c --- /dev/null +++ b/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js new file mode 100644 index 000000000..54b3c4638 --- /dev/null +++ b/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/_static/copybutton.css b/_static/copybutton.css new file mode 100644 index 000000000..f1916ec7d --- /dev/null +++ b/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/_static/copybutton.js b/_static/copybutton.js new file mode 100644 index 000000000..2ea7ff3e2 --- /dev/null +++ b/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '', false, true, true, true, '', '') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js new file mode 100644 index 000000000..dbe1aaad7 --- /dev/null +++ b/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css new file mode 100644 index 000000000..c718cee44 --- /dev/null +++ b/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 000000000..6cb600001 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 000000000..7059e2314 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 000000000..f815f63f9 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 000000000..f2c76e5bd Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/_static/css/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/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 000000000..88ad05b9f Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 000000000..c4e3d804b Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff new file mode 100644 index 000000000..c6dff51f0 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 000000000..bb195043c Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 000000000..76114bc03 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 000000000..3404f37e2 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff new file mode 100644 index 000000000..ae1307ff5 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 000000000..3bf984332 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ diff --git a/_static/css/theme.css b/_static/css/theme.css new file mode 100644 index 000000000..19a446a0e --- /dev/null +++ b/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * 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-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{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}.fa-lg{font-size:1.33333em;line-height:.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.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-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:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{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:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.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}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 000000000..4d67807d1 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 000000000..7e4c114f2 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/_static/file.png differ diff --git a/_static/jquery.js b/_static/jquery.js new file mode 100644 index 000000000..c4c6022f2 --- /dev/null +++ b/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.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(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=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))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(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&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(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&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(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 ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);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&&E){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=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(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(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===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]||se.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]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(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(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(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=se.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 j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.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 S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(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 je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.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)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.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),m(t)&&(t=t.call(e,n,S.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)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.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"===S.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"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(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)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(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?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.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)}}),S.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){S.fn[n]=function(e,t){return 0",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/html5shiv.min.js b/_static/js/html5shiv.min.js new file mode 100644 index 000000000..cd1c674f5 --- /dev/null +++ b/_static/js/html5shiv.min.js @@ -0,0 +1,4 @@ +/** +* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document); \ No newline at end of file diff --git a/_static/js/theme.js b/_static/js/theme.js new file mode 100644 index 000000000..1fddb6ee4 --- /dev/null +++ b/_static/js/theme.js @@ -0,0 +1 @@ +!function(n){var e={};function t(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return n[i].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=n,t.c=e,t.d=function(n,e,i){t.o(n,e)||Object.defineProperty(n,e,{enumerable:!0,get:i})},t.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},t.t=function(n,e){if(1&e&&(n=t(n)),8&e)return n;if(4&e&&"object"==typeof n&&n&&n.__esModule)return n;var i=Object.create(null);if(t.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:n}),2&e&&"string"!=typeof n)for(var o in n)t.d(i,o,function(e){return n[e]}.bind(null,o));return i},t.n=function(n){var e=n&&n.__esModule?function(){return n.default}:function(){return n};return t.d(e,"a",e),e},t.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},t.p="",t(t.s=0)}([function(n,e,t){t(1),n.exports=t(3)},function(n,e,t){(function(){var e="undefined"!=typeof window?window.jQuery:t(2);n.exports.ThemeNav={navBar:null,win:null,winScroll:!1,winResize:!1,linkScroll:!1,winPosition:0,winHeight:null,docHeight:null,isRunning:!1,enable:function(n){var t=this;void 0===n&&(n=!0),t.isRunning||(t.isRunning=!0,e((function(e){t.init(e),t.reset(),t.win.on("hashchange",t.reset),n&&t.win.on("scroll",(function(){t.linkScroll||t.winScroll||(t.winScroll=!0,requestAnimationFrame((function(){t.onScroll()})))})),t.win.on("resize",(function(){t.winResize||(t.winResize=!0,requestAnimationFrame((function(){t.onResize()})))})),t.onResize()})))},enableSticky:function(){this.enable(!0)},init:function(n){n(document);var e=this;this.navBar=n("div.wy-side-scroll:first"),this.win=n(window),n(document).on("click","[data-toggle='wy-nav-top']",(function(){n("[data-toggle='wy-nav-shift']").toggleClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift")})).on("click",".wy-menu-vertical .current ul li a",(function(){var t=n(this);n("[data-toggle='wy-nav-shift']").removeClass("shift"),n("[data-toggle='rst-versions']").toggleClass("shift"),e.toggleCurrent(t),e.hashChange()})).on("click","[data-toggle='rst-current-version']",(function(){n("[data-toggle='rst-versions']").toggleClass("shift-up")})),n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minipres.js b/_static/minipres.js new file mode 100644 index 000000000..ad11c8713 --- /dev/null +++ b/_static/minipres.js @@ -0,0 +1,223 @@ +// Add goTo method to elements +// http://stackoverflow.com/questions/4801655/how-to-go-to-a-specific-element-on-page +(function($) { + $.fn.goTo = function() { + $('html, body').animate({ + scrollTop: $(this).offset().top //+ 'px' + }, 'fast'); + return this; // for chaining... + } +})(jQuery); + +// NO good way to do this!. Copy a hack from here +// https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript +// https://stackoverflow.com/a/2880929 +var urlParams; +(window.onpopstate = function () { + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, + query = window.location.search.substring(1); + urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); +})(); + +// Select heading levels +var maxHeading = urlParams['h'] +if (maxHeading === undefined) maxHeading = 2 +var headingLevels = []; +for (h=2 ; h (sections.length-1) ) { + // if we would scroll past bottom, or above top, do nothing + return; + } + + console.log('xxxxxx'); + var targetSection = sections[targetPos]; + console.log(targetSection, typeof(targetSection)); + + // Return targetSection top and height + var secProperties = section_top_and_height(targetSection); + var top = secProperties['top']; + var height = secProperties['height'] + var win_height = window.innerHeight; + //console.info(top, height, win_height) + + var scroll_to = 0; + if (height >= win_height || height == 0) { + scroll_to = top; + } else { + scroll_to = top - (win_height-height)/3.; + } + //console.info(top, height, win_height, scroll_to) + + $('html, body').animate({ + scrollTop: scroll_to //+ 'px' + }, 'fast'); + +} + + +function minipres() { + /* Enable the minipres mode: + - call the hide() function + - set up the scrolling listener + */ + document.addEventListener('keydown', function (event) { + switch(event.which) { + case 37: // left + switch_slide(-1); + event.preventDefault(); + return false; + break; + //case 38: // up + case 39: // right + switch_slide(+1); + event.preventDefault(); + return false; + break; + //case 40: // down + default: + return; // exit this handler for other keys + } + }, true) + + hide() + + // Increase space between sections + //$("div .section").css('margin-bottom', '50%'); + $(sectionSelector).css('margin-top', '50%'); + + // Reduce size/color of other sections + if (hiddenSectionSelector.length > 0) { + var hideNodes = $(hiddenSectionSelector); + console.log(typeof hideNodes, hideNodes); + for (node in hideNodes) { + console.log("a", typeof node, node); + node = hideNodes[node]; // what's right way to iterate values? + console.log("b", typeof node, node); + if (node.parentNode && node.parentNode.className == "section") { + node = node.parentNode; + console.log("c", typeof node, node); + //node.css['transform'] = 'scale(.5)'; + //node.css['transform-origin'] = 'top center'; + $(node).css('color', 'lightgrey'); + //$(node).css('font-size', '20%'); + //$(node).css('visibility', 'collapse'); + //ntahousnatouhasno; + } + } + } +} + +function hide() { + /* Hide all non-essential elements on the page + */ + + // This is for sphinx_rst_theme and readthedocs + $(".wy-nav-side").remove(); + $(".wy-nav-content-wrap").css('margin-left', 0); + $('.rst-versions').remove(); // readthedocs version selector + + // Add other formats here. +} + + +var slideshow = minipres; + +if (window.location.search.match(/[?&](minipres|slideshow|pres)([=&]|$)/) ) { + //minipres() + window.addEventListener("load", minipres); +} else if (window.location.search.match(/[?&](plain)([=&]|$)/) ) { + window.addEventListener("load", hide); +} diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 000000000..d96755fda Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css b/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css new file mode 100644 index 000000000..335663106 --- /dev/null +++ b/_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css @@ -0,0 +1,2342 @@ +/* Variables */ +:root { + --mystnb-source-bg-color: #f7f7f7; + --mystnb-stdout-bg-color: #fcfcfc; + --mystnb-stderr-bg-color: #fdd; + --mystnb-traceback-bg-color: #fcfcfc; + --mystnb-source-border-color: #ccc; + --mystnb-source-margin-color: green; + --mystnb-stdout-border-color: #f7f7f7; + --mystnb-stderr-border-color: #f7f7f7; + --mystnb-traceback-border-color: #ffd6d6; + --mystnb-hide-prompt-opacity: 70%; + --mystnb-source-border-radius: .4em; + --mystnb-source-border-width: 1px; +} + +/* Whole cell */ +div.container.cell { + padding-left: 0; + margin-bottom: 1em; +} + +/* Removing all background formatting so we can control at the div level */ +.cell_input div.highlight, +.cell_output pre, +.cell_input pre, +.cell_output .output { + border: none; + box-shadow: none; +} + +.cell_output .output pre, +.cell_input pre { + margin: 0px; +} + +/* Input cells */ +div.cell div.cell_input, +div.cell details.above-input>summary { + padding-left: 0em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + background-color: var(--mystnb-source-bg-color); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; + border-radius: var(--mystnb-source-border-radius); +} + +div.cell_input>div, +div.cell_output div.output>div.highlight { + margin: 0em !important; + border: none !important; +} + +/* All cell outputs */ +.cell_output { + padding-left: 1em; + padding-right: 0em; + margin-top: 1em; +} + +/* Text outputs from cells */ +.cell_output .output.text_plain, +.cell_output .output.traceback, +.cell_output .output.stream, +.cell_output .output.stderr { + margin-top: 1em; + margin-bottom: 0em; + box-shadow: none; +} + +.cell_output .output.text_plain, +.cell_output .output.stream { + background: var(--mystnb-stdout-bg-color); + border: 1px solid var(--mystnb-stdout-border-color); +} + +.cell_output .output.stderr { + background: var(--mystnb-stderr-bg-color); + border: 1px solid var(--mystnb-stderr-border-color); +} + +.cell_output .output.traceback { + background: var(--mystnb-traceback-bg-color); + border: 1px solid var(--mystnb-traceback-border-color); +} + +/* Collapsible cell content */ +div.cell details.above-input div.cell_input { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-top: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; +} + +div.cell div.cell_input.above-output-prompt { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +div.cell details.above-input>summary { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: var(--mystnb-source-border-width) var(--mystnb-source-border-color) dashed; + padding-left: 1em; + margin-bottom: 0; +} + +div.cell details.above-output>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.below-input>summary { + background-color: var(--mystnb-source-bg-color); + padding-left: 1em; + padding-right: 0em; + border: var(--mystnb-source-border-width) var(--mystnb-source-border-color) solid; + border-top: none; + border-bottom-left-radius: var(--mystnb-source-border-radius); + border-bottom-right-radius: var(--mystnb-source-border-radius); + border-left-color: var(--mystnb-source-margin-color); + border-left-width: medium; +} + +div.cell details.hide>summary>span { + opacity: var(--mystnb-hide-prompt-opacity); +} + +div.cell details.hide[open]>summary>span.collapsed { + display: none; +} + +div.cell details.hide:not([open])>summary>span.expanded { + display: none; +} + +@keyframes collapsed-fade-in { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} +div.cell details.hide[open]>summary~* { + -moz-animation: collapsed-fade-in 0.3s ease-in-out; + -webkit-animation: collapsed-fade-in 0.3s ease-in-out; + animation: collapsed-fade-in 0.3s ease-in-out; +} + +/* Math align to the left */ +.cell_output .MathJax_Display { + text-align: left !important; +} + +/* Pandas tables. Pulled from the Jupyter / nbsphinx CSS */ +div.cell_output table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 1em; + table-layout: fixed; +} + +div.cell_output thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} + +div.cell_output tr, +div.cell_output th, +div.cell_output td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} + +div.cell_output th { + font-weight: bold; +} + +div.cell_output tbody tr:nth-child(odd) { + background: #f5f5f5; +} + +div.cell_output tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + +/** source code line numbers **/ +span.linenos { + opacity: 0.5; +} + +/* Inline text from `paste` operation */ + +span.pasted-text { + font-weight: bold; +} + +span.pasted-inline img { + max-height: 2em; +} + +tbody span.pasted-inline img { + max-height: none; +} + +/* Font colors for translated ANSI escape sequences +Color values are copied from Jupyter Notebook +https://github.com/jupyter/notebook/blob/52581f8eda9b319eb0390ac77fe5903c38f81e3e/notebook/static/notebook/less/ansicolors.less#L14-L21 +Background colors from +https://nbsphinx.readthedocs.io/en/latest/code-cells.html#ANSI-Colors +*/ +div.highlight .-Color-Bold { + font-weight: bold; +} + +div.highlight .-Color[class*=-Black] { + color: #3E424D +} + +div.highlight .-Color[class*=-Red] { + color: #E75C58 +} + +div.highlight .-Color[class*=-Green] { + color: #00A250 +} + +div.highlight .-Color[class*=-Yellow] { + color: #DDB62B +} + +div.highlight .-Color[class*=-Blue] { + color: #208FFB +} + +div.highlight .-Color[class*=-Magenta] { + color: #D160C4 +} + +div.highlight .-Color[class*=-Cyan] { + color: #60C6C8 +} + +div.highlight .-Color[class*=-White] { + color: #C5C1B4 +} + +div.highlight .-Color[class*=-BGBlack] { + background-color: #3E424D +} + +div.highlight .-Color[class*=-BGRed] { + background-color: #E75C58 +} + +div.highlight .-Color[class*=-BGGreen] { + background-color: #00A250 +} + +div.highlight .-Color[class*=-BGYellow] { + background-color: #DDB62B +} + +div.highlight .-Color[class*=-BGBlue] { + background-color: #208FFB +} + +div.highlight .-Color[class*=-BGMagenta] { + background-color: #D160C4 +} + +div.highlight .-Color[class*=-BGCyan] { + background-color: #60C6C8 +} + +div.highlight .-Color[class*=-BGWhite] { + background-color: #C5C1B4 +} + +/* Font colors for 8-bit ANSI */ + +div.highlight .-Color[class*=-C0] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC0] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C1] { + color: #800000 +} + +div.highlight .-Color[class*=-BGC1] { + background-color: #800000 +} + +div.highlight .-Color[class*=-C2] { + color: #008000 +} + +div.highlight .-Color[class*=-BGC2] { + background-color: #008000 +} + +div.highlight .-Color[class*=-C3] { + color: #808000 +} + +div.highlight .-Color[class*=-BGC3] { + background-color: #808000 +} + +div.highlight .-Color[class*=-C4] { + color: #000080 +} + +div.highlight .-Color[class*=-BGC4] { + background-color: #000080 +} + +div.highlight .-Color[class*=-C5] { + color: #800080 +} + +div.highlight .-Color[class*=-BGC5] { + background-color: #800080 +} + +div.highlight .-Color[class*=-C6] { + color: #008080 +} + +div.highlight .-Color[class*=-BGC6] { + background-color: #008080 +} + +div.highlight .-Color[class*=-C7] { + color: #C0C0C0 +} + +div.highlight .-Color[class*=-BGC7] { + background-color: #C0C0C0 +} + +div.highlight .-Color[class*=-C8] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC8] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C9] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC9] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C10] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC10] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C11] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC11] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C12] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC12] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C13] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC13] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C14] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC14] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C15] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC15] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C16] { + color: #000000 +} + +div.highlight .-Color[class*=-BGC16] { + background-color: #000000 +} + +div.highlight .-Color[class*=-C17] { + color: #00005F +} + +div.highlight .-Color[class*=-BGC17] { + background-color: #00005F +} + +div.highlight .-Color[class*=-C18] { + color: #000087 +} + +div.highlight .-Color[class*=-BGC18] { + background-color: #000087 +} + +div.highlight .-Color[class*=-C19] { + color: #0000AF +} + +div.highlight .-Color[class*=-BGC19] { + background-color: #0000AF +} + +div.highlight .-Color[class*=-C20] { + color: #0000D7 +} + +div.highlight .-Color[class*=-BGC20] { + background-color: #0000D7 +} + +div.highlight .-Color[class*=-C21] { + color: #0000FF +} + +div.highlight .-Color[class*=-BGC21] { + background-color: #0000FF +} + +div.highlight .-Color[class*=-C22] { + color: #005F00 +} + +div.highlight .-Color[class*=-BGC22] { + background-color: #005F00 +} + +div.highlight .-Color[class*=-C23] { + color: #005F5F +} + +div.highlight .-Color[class*=-BGC23] { + background-color: #005F5F +} + +div.highlight .-Color[class*=-C24] { + color: #005F87 +} + +div.highlight .-Color[class*=-BGC24] { + background-color: #005F87 +} + +div.highlight .-Color[class*=-C25] { + color: #005FAF +} + +div.highlight .-Color[class*=-BGC25] { + background-color: #005FAF +} + +div.highlight .-Color[class*=-C26] { + color: #005FD7 +} + +div.highlight .-Color[class*=-BGC26] { + background-color: #005FD7 +} + +div.highlight .-Color[class*=-C27] { + color: #005FFF +} + +div.highlight .-Color[class*=-BGC27] { + background-color: #005FFF +} + +div.highlight .-Color[class*=-C28] { + color: #008700 +} + +div.highlight .-Color[class*=-BGC28] { + background-color: #008700 +} + +div.highlight .-Color[class*=-C29] { + color: #00875F +} + +div.highlight .-Color[class*=-BGC29] { + background-color: #00875F +} + +div.highlight .-Color[class*=-C30] { + color: #008787 +} + +div.highlight .-Color[class*=-BGC30] { + background-color: #008787 +} + +div.highlight .-Color[class*=-C31] { + color: #0087AF +} + +div.highlight .-Color[class*=-BGC31] { + background-color: #0087AF +} + +div.highlight .-Color[class*=-C32] { + color: #0087D7 +} + +div.highlight .-Color[class*=-BGC32] { + background-color: #0087D7 +} + +div.highlight .-Color[class*=-C33] { + color: #0087FF +} + +div.highlight .-Color[class*=-BGC33] { + background-color: #0087FF +} + +div.highlight .-Color[class*=-C34] { + color: #00AF00 +} + +div.highlight .-Color[class*=-BGC34] { + background-color: #00AF00 +} + +div.highlight .-Color[class*=-C35] { + color: #00AF5F +} + +div.highlight .-Color[class*=-BGC35] { + background-color: #00AF5F +} + +div.highlight .-Color[class*=-C36] { + color: #00AF87 +} + +div.highlight .-Color[class*=-BGC36] { + background-color: #00AF87 +} + +div.highlight .-Color[class*=-C37] { + color: #00AFAF +} + +div.highlight .-Color[class*=-BGC37] { + background-color: #00AFAF +} + +div.highlight .-Color[class*=-C38] { + color: #00AFD7 +} + +div.highlight .-Color[class*=-BGC38] { + background-color: #00AFD7 +} + +div.highlight .-Color[class*=-C39] { + color: #00AFFF +} + +div.highlight .-Color[class*=-BGC39] { + background-color: #00AFFF +} + +div.highlight .-Color[class*=-C40] { + color: #00D700 +} + +div.highlight .-Color[class*=-BGC40] { + background-color: #00D700 +} + +div.highlight .-Color[class*=-C41] { + color: #00D75F +} + +div.highlight .-Color[class*=-BGC41] { + background-color: #00D75F +} + +div.highlight .-Color[class*=-C42] { + color: #00D787 +} + +div.highlight .-Color[class*=-BGC42] { + background-color: #00D787 +} + +div.highlight .-Color[class*=-C43] { + color: #00D7AF +} + +div.highlight .-Color[class*=-BGC43] { + background-color: #00D7AF +} + +div.highlight .-Color[class*=-C44] { + color: #00D7D7 +} + +div.highlight .-Color[class*=-BGC44] { + background-color: #00D7D7 +} + +div.highlight .-Color[class*=-C45] { + color: #00D7FF +} + +div.highlight .-Color[class*=-BGC45] { + background-color: #00D7FF +} + +div.highlight .-Color[class*=-C46] { + color: #00FF00 +} + +div.highlight .-Color[class*=-BGC46] { + background-color: #00FF00 +} + +div.highlight .-Color[class*=-C47] { + color: #00FF5F +} + +div.highlight .-Color[class*=-BGC47] { + background-color: #00FF5F +} + +div.highlight .-Color[class*=-C48] { + color: #00FF87 +} + +div.highlight .-Color[class*=-BGC48] { + background-color: #00FF87 +} + +div.highlight .-Color[class*=-C49] { + color: #00FFAF +} + +div.highlight .-Color[class*=-BGC49] { + background-color: #00FFAF +} + +div.highlight .-Color[class*=-C50] { + color: #00FFD7 +} + +div.highlight .-Color[class*=-BGC50] { + background-color: #00FFD7 +} + +div.highlight .-Color[class*=-C51] { + color: #00FFFF +} + +div.highlight .-Color[class*=-BGC51] { + background-color: #00FFFF +} + +div.highlight .-Color[class*=-C52] { + color: #5F0000 +} + +div.highlight .-Color[class*=-BGC52] { + background-color: #5F0000 +} + +div.highlight .-Color[class*=-C53] { + color: #5F005F +} + +div.highlight .-Color[class*=-BGC53] { + background-color: #5F005F +} + +div.highlight .-Color[class*=-C54] { + color: #5F0087 +} + +div.highlight .-Color[class*=-BGC54] { + background-color: #5F0087 +} + +div.highlight .-Color[class*=-C55] { + color: #5F00AF +} + +div.highlight .-Color[class*=-BGC55] { + background-color: #5F00AF +} + +div.highlight .-Color[class*=-C56] { + color: #5F00D7 +} + +div.highlight .-Color[class*=-BGC56] { + background-color: #5F00D7 +} + +div.highlight .-Color[class*=-C57] { + color: #5F00FF +} + +div.highlight .-Color[class*=-BGC57] { + background-color: #5F00FF +} + +div.highlight .-Color[class*=-C58] { + color: #5F5F00 +} + +div.highlight .-Color[class*=-BGC58] { + background-color: #5F5F00 +} + +div.highlight .-Color[class*=-C59] { + color: #5F5F5F +} + +div.highlight .-Color[class*=-BGC59] { + background-color: #5F5F5F +} + +div.highlight .-Color[class*=-C60] { + color: #5F5F87 +} + +div.highlight .-Color[class*=-BGC60] { + background-color: #5F5F87 +} + +div.highlight .-Color[class*=-C61] { + color: #5F5FAF +} + +div.highlight .-Color[class*=-BGC61] { + background-color: #5F5FAF +} + +div.highlight .-Color[class*=-C62] { + color: #5F5FD7 +} + +div.highlight .-Color[class*=-BGC62] { + background-color: #5F5FD7 +} + +div.highlight .-Color[class*=-C63] { + color: #5F5FFF +} + +div.highlight .-Color[class*=-BGC63] { + background-color: #5F5FFF +} + +div.highlight .-Color[class*=-C64] { + color: #5F8700 +} + +div.highlight .-Color[class*=-BGC64] { + background-color: #5F8700 +} + +div.highlight .-Color[class*=-C65] { + color: #5F875F +} + +div.highlight .-Color[class*=-BGC65] { + background-color: #5F875F +} + +div.highlight .-Color[class*=-C66] { + color: #5F8787 +} + +div.highlight .-Color[class*=-BGC66] { + background-color: #5F8787 +} + +div.highlight .-Color[class*=-C67] { + color: #5F87AF +} + +div.highlight .-Color[class*=-BGC67] { + background-color: #5F87AF +} + +div.highlight .-Color[class*=-C68] { + color: #5F87D7 +} + +div.highlight .-Color[class*=-BGC68] { + background-color: #5F87D7 +} + +div.highlight .-Color[class*=-C69] { + color: #5F87FF +} + +div.highlight .-Color[class*=-BGC69] { + background-color: #5F87FF +} + +div.highlight .-Color[class*=-C70] { + color: #5FAF00 +} + +div.highlight .-Color[class*=-BGC70] { + background-color: #5FAF00 +} + +div.highlight .-Color[class*=-C71] { + color: #5FAF5F +} + +div.highlight .-Color[class*=-BGC71] { + background-color: #5FAF5F +} + +div.highlight .-Color[class*=-C72] { + color: #5FAF87 +} + +div.highlight .-Color[class*=-BGC72] { + background-color: #5FAF87 +} + +div.highlight .-Color[class*=-C73] { + color: #5FAFAF +} + +div.highlight .-Color[class*=-BGC73] { + background-color: #5FAFAF +} + +div.highlight .-Color[class*=-C74] { + color: #5FAFD7 +} + +div.highlight .-Color[class*=-BGC74] { + background-color: #5FAFD7 +} + +div.highlight .-Color[class*=-C75] { + color: #5FAFFF +} + +div.highlight .-Color[class*=-BGC75] { + background-color: #5FAFFF +} + +div.highlight .-Color[class*=-C76] { + color: #5FD700 +} + +div.highlight .-Color[class*=-BGC76] { + background-color: #5FD700 +} + +div.highlight .-Color[class*=-C77] { + color: #5FD75F +} + +div.highlight .-Color[class*=-BGC77] { + background-color: #5FD75F +} + +div.highlight .-Color[class*=-C78] { + color: #5FD787 +} + +div.highlight .-Color[class*=-BGC78] { + background-color: #5FD787 +} + +div.highlight .-Color[class*=-C79] { + color: #5FD7AF +} + +div.highlight .-Color[class*=-BGC79] { + background-color: #5FD7AF +} + +div.highlight .-Color[class*=-C80] { + color: #5FD7D7 +} + +div.highlight .-Color[class*=-BGC80] { + background-color: #5FD7D7 +} + +div.highlight .-Color[class*=-C81] { + color: #5FD7FF +} + +div.highlight .-Color[class*=-BGC81] { + background-color: #5FD7FF +} + +div.highlight .-Color[class*=-C82] { + color: #5FFF00 +} + +div.highlight .-Color[class*=-BGC82] { + background-color: #5FFF00 +} + +div.highlight .-Color[class*=-C83] { + color: #5FFF5F +} + +div.highlight .-Color[class*=-BGC83] { + background-color: #5FFF5F +} + +div.highlight .-Color[class*=-C84] { + color: #5FFF87 +} + +div.highlight .-Color[class*=-BGC84] { + background-color: #5FFF87 +} + +div.highlight .-Color[class*=-C85] { + color: #5FFFAF +} + +div.highlight .-Color[class*=-BGC85] { + background-color: #5FFFAF +} + +div.highlight .-Color[class*=-C86] { + color: #5FFFD7 +} + +div.highlight .-Color[class*=-BGC86] { + background-color: #5FFFD7 +} + +div.highlight .-Color[class*=-C87] { + color: #5FFFFF +} + +div.highlight .-Color[class*=-BGC87] { + background-color: #5FFFFF +} + +div.highlight .-Color[class*=-C88] { + color: #870000 +} + +div.highlight .-Color[class*=-BGC88] { + background-color: #870000 +} + +div.highlight .-Color[class*=-C89] { + color: #87005F +} + +div.highlight .-Color[class*=-BGC89] { + background-color: #87005F +} + +div.highlight .-Color[class*=-C90] { + color: #870087 +} + +div.highlight .-Color[class*=-BGC90] { + background-color: #870087 +} + +div.highlight .-Color[class*=-C91] { + color: #8700AF +} + +div.highlight .-Color[class*=-BGC91] { + background-color: #8700AF +} + +div.highlight .-Color[class*=-C92] { + color: #8700D7 +} + +div.highlight .-Color[class*=-BGC92] { + background-color: #8700D7 +} + +div.highlight .-Color[class*=-C93] { + color: #8700FF +} + +div.highlight .-Color[class*=-BGC93] { + background-color: #8700FF +} + +div.highlight .-Color[class*=-C94] { + color: #875F00 +} + +div.highlight .-Color[class*=-BGC94] { + background-color: #875F00 +} + +div.highlight .-Color[class*=-C95] { + color: #875F5F +} + +div.highlight .-Color[class*=-BGC95] { + background-color: #875F5F +} + +div.highlight .-Color[class*=-C96] { + color: #875F87 +} + +div.highlight .-Color[class*=-BGC96] { + background-color: #875F87 +} + +div.highlight .-Color[class*=-C97] { + color: #875FAF +} + +div.highlight .-Color[class*=-BGC97] { + background-color: #875FAF +} + +div.highlight .-Color[class*=-C98] { + color: #875FD7 +} + +div.highlight .-Color[class*=-BGC98] { + background-color: #875FD7 +} + +div.highlight .-Color[class*=-C99] { + color: #875FFF +} + +div.highlight .-Color[class*=-BGC99] { + background-color: #875FFF +} + +div.highlight .-Color[class*=-C100] { + color: #878700 +} + +div.highlight .-Color[class*=-BGC100] { + background-color: #878700 +} + +div.highlight .-Color[class*=-C101] { + color: #87875F +} + +div.highlight .-Color[class*=-BGC101] { + background-color: #87875F +} + +div.highlight .-Color[class*=-C102] { + color: #878787 +} + +div.highlight .-Color[class*=-BGC102] { + background-color: #878787 +} + +div.highlight .-Color[class*=-C103] { + color: #8787AF +} + +div.highlight .-Color[class*=-BGC103] { + background-color: #8787AF +} + +div.highlight .-Color[class*=-C104] { + color: #8787D7 +} + +div.highlight .-Color[class*=-BGC104] { + background-color: #8787D7 +} + +div.highlight .-Color[class*=-C105] { + color: #8787FF +} + +div.highlight .-Color[class*=-BGC105] { + background-color: #8787FF +} + +div.highlight .-Color[class*=-C106] { + color: #87AF00 +} + +div.highlight .-Color[class*=-BGC106] { + background-color: #87AF00 +} + +div.highlight .-Color[class*=-C107] { + color: #87AF5F +} + +div.highlight .-Color[class*=-BGC107] { + background-color: #87AF5F +} + +div.highlight .-Color[class*=-C108] { + color: #87AF87 +} + +div.highlight .-Color[class*=-BGC108] { + background-color: #87AF87 +} + +div.highlight .-Color[class*=-C109] { + color: #87AFAF +} + +div.highlight .-Color[class*=-BGC109] { + background-color: #87AFAF +} + +div.highlight .-Color[class*=-C110] { + color: #87AFD7 +} + +div.highlight .-Color[class*=-BGC110] { + background-color: #87AFD7 +} + +div.highlight .-Color[class*=-C111] { + color: #87AFFF +} + +div.highlight .-Color[class*=-BGC111] { + background-color: #87AFFF +} + +div.highlight .-Color[class*=-C112] { + color: #87D700 +} + +div.highlight .-Color[class*=-BGC112] { + background-color: #87D700 +} + +div.highlight .-Color[class*=-C113] { + color: #87D75F +} + +div.highlight .-Color[class*=-BGC113] { + background-color: #87D75F +} + +div.highlight .-Color[class*=-C114] { + color: #87D787 +} + +div.highlight .-Color[class*=-BGC114] { + background-color: #87D787 +} + +div.highlight .-Color[class*=-C115] { + color: #87D7AF +} + +div.highlight .-Color[class*=-BGC115] { + background-color: #87D7AF +} + +div.highlight .-Color[class*=-C116] { + color: #87D7D7 +} + +div.highlight .-Color[class*=-BGC116] { + background-color: #87D7D7 +} + +div.highlight .-Color[class*=-C117] { + color: #87D7FF +} + +div.highlight .-Color[class*=-BGC117] { + background-color: #87D7FF +} + +div.highlight .-Color[class*=-C118] { + color: #87FF00 +} + +div.highlight .-Color[class*=-BGC118] { + background-color: #87FF00 +} + +div.highlight .-Color[class*=-C119] { + color: #87FF5F +} + +div.highlight .-Color[class*=-BGC119] { + background-color: #87FF5F +} + +div.highlight .-Color[class*=-C120] { + color: #87FF87 +} + +div.highlight .-Color[class*=-BGC120] { + background-color: #87FF87 +} + +div.highlight .-Color[class*=-C121] { + color: #87FFAF +} + +div.highlight .-Color[class*=-BGC121] { + background-color: #87FFAF +} + +div.highlight .-Color[class*=-C122] { + color: #87FFD7 +} + +div.highlight .-Color[class*=-BGC122] { + background-color: #87FFD7 +} + +div.highlight .-Color[class*=-C123] { + color: #87FFFF +} + +div.highlight .-Color[class*=-BGC123] { + background-color: #87FFFF +} + +div.highlight .-Color[class*=-C124] { + color: #AF0000 +} + +div.highlight .-Color[class*=-BGC124] { + background-color: #AF0000 +} + +div.highlight .-Color[class*=-C125] { + color: #AF005F +} + +div.highlight .-Color[class*=-BGC125] { + background-color: #AF005F +} + +div.highlight .-Color[class*=-C126] { + color: #AF0087 +} + +div.highlight .-Color[class*=-BGC126] { + background-color: #AF0087 +} + +div.highlight .-Color[class*=-C127] { + color: #AF00AF +} + +div.highlight .-Color[class*=-BGC127] { + background-color: #AF00AF +} + +div.highlight .-Color[class*=-C128] { + color: #AF00D7 +} + +div.highlight .-Color[class*=-BGC128] { + background-color: #AF00D7 +} + +div.highlight .-Color[class*=-C129] { + color: #AF00FF +} + +div.highlight .-Color[class*=-BGC129] { + background-color: #AF00FF +} + +div.highlight .-Color[class*=-C130] { + color: #AF5F00 +} + +div.highlight .-Color[class*=-BGC130] { + background-color: #AF5F00 +} + +div.highlight .-Color[class*=-C131] { + color: #AF5F5F +} + +div.highlight .-Color[class*=-BGC131] { + background-color: #AF5F5F +} + +div.highlight .-Color[class*=-C132] { + color: #AF5F87 +} + +div.highlight .-Color[class*=-BGC132] { + background-color: #AF5F87 +} + +div.highlight .-Color[class*=-C133] { + color: #AF5FAF +} + +div.highlight .-Color[class*=-BGC133] { + background-color: #AF5FAF +} + +div.highlight .-Color[class*=-C134] { + color: #AF5FD7 +} + +div.highlight .-Color[class*=-BGC134] { + background-color: #AF5FD7 +} + +div.highlight .-Color[class*=-C135] { + color: #AF5FFF +} + +div.highlight .-Color[class*=-BGC135] { + background-color: #AF5FFF +} + +div.highlight .-Color[class*=-C136] { + color: #AF8700 +} + +div.highlight .-Color[class*=-BGC136] { + background-color: #AF8700 +} + +div.highlight .-Color[class*=-C137] { + color: #AF875F +} + +div.highlight .-Color[class*=-BGC137] { + background-color: #AF875F +} + +div.highlight .-Color[class*=-C138] { + color: #AF8787 +} + +div.highlight .-Color[class*=-BGC138] { + background-color: #AF8787 +} + +div.highlight .-Color[class*=-C139] { + color: #AF87AF +} + +div.highlight .-Color[class*=-BGC139] { + background-color: #AF87AF +} + +div.highlight .-Color[class*=-C140] { + color: #AF87D7 +} + +div.highlight .-Color[class*=-BGC140] { + background-color: #AF87D7 +} + +div.highlight .-Color[class*=-C141] { + color: #AF87FF +} + +div.highlight .-Color[class*=-BGC141] { + background-color: #AF87FF +} + +div.highlight .-Color[class*=-C142] { + color: #AFAF00 +} + +div.highlight .-Color[class*=-BGC142] { + background-color: #AFAF00 +} + +div.highlight .-Color[class*=-C143] { + color: #AFAF5F +} + +div.highlight .-Color[class*=-BGC143] { + background-color: #AFAF5F +} + +div.highlight .-Color[class*=-C144] { + color: #AFAF87 +} + +div.highlight .-Color[class*=-BGC144] { + background-color: #AFAF87 +} + +div.highlight .-Color[class*=-C145] { + color: #AFAFAF +} + +div.highlight .-Color[class*=-BGC145] { + background-color: #AFAFAF +} + +div.highlight .-Color[class*=-C146] { + color: #AFAFD7 +} + +div.highlight .-Color[class*=-BGC146] { + background-color: #AFAFD7 +} + +div.highlight .-Color[class*=-C147] { + color: #AFAFFF +} + +div.highlight .-Color[class*=-BGC147] { + background-color: #AFAFFF +} + +div.highlight .-Color[class*=-C148] { + color: #AFD700 +} + +div.highlight .-Color[class*=-BGC148] { + background-color: #AFD700 +} + +div.highlight .-Color[class*=-C149] { + color: #AFD75F +} + +div.highlight .-Color[class*=-BGC149] { + background-color: #AFD75F +} + +div.highlight .-Color[class*=-C150] { + color: #AFD787 +} + +div.highlight .-Color[class*=-BGC150] { + background-color: #AFD787 +} + +div.highlight .-Color[class*=-C151] { + color: #AFD7AF +} + +div.highlight .-Color[class*=-BGC151] { + background-color: #AFD7AF +} + +div.highlight .-Color[class*=-C152] { + color: #AFD7D7 +} + +div.highlight .-Color[class*=-BGC152] { + background-color: #AFD7D7 +} + +div.highlight .-Color[class*=-C153] { + color: #AFD7FF +} + +div.highlight .-Color[class*=-BGC153] { + background-color: #AFD7FF +} + +div.highlight .-Color[class*=-C154] { + color: #AFFF00 +} + +div.highlight .-Color[class*=-BGC154] { + background-color: #AFFF00 +} + +div.highlight .-Color[class*=-C155] { + color: #AFFF5F +} + +div.highlight .-Color[class*=-BGC155] { + background-color: #AFFF5F +} + +div.highlight .-Color[class*=-C156] { + color: #AFFF87 +} + +div.highlight .-Color[class*=-BGC156] { + background-color: #AFFF87 +} + +div.highlight .-Color[class*=-C157] { + color: #AFFFAF +} + +div.highlight .-Color[class*=-BGC157] { + background-color: #AFFFAF +} + +div.highlight .-Color[class*=-C158] { + color: #AFFFD7 +} + +div.highlight .-Color[class*=-BGC158] { + background-color: #AFFFD7 +} + +div.highlight .-Color[class*=-C159] { + color: #AFFFFF +} + +div.highlight .-Color[class*=-BGC159] { + background-color: #AFFFFF +} + +div.highlight .-Color[class*=-C160] { + color: #D70000 +} + +div.highlight .-Color[class*=-BGC160] { + background-color: #D70000 +} + +div.highlight .-Color[class*=-C161] { + color: #D7005F +} + +div.highlight .-Color[class*=-BGC161] { + background-color: #D7005F +} + +div.highlight .-Color[class*=-C162] { + color: #D70087 +} + +div.highlight .-Color[class*=-BGC162] { + background-color: #D70087 +} + +div.highlight .-Color[class*=-C163] { + color: #D700AF +} + +div.highlight .-Color[class*=-BGC163] { + background-color: #D700AF +} + +div.highlight .-Color[class*=-C164] { + color: #D700D7 +} + +div.highlight .-Color[class*=-BGC164] { + background-color: #D700D7 +} + +div.highlight .-Color[class*=-C165] { + color: #D700FF +} + +div.highlight .-Color[class*=-BGC165] { + background-color: #D700FF +} + +div.highlight .-Color[class*=-C166] { + color: #D75F00 +} + +div.highlight .-Color[class*=-BGC166] { + background-color: #D75F00 +} + +div.highlight .-Color[class*=-C167] { + color: #D75F5F +} + +div.highlight .-Color[class*=-BGC167] { + background-color: #D75F5F +} + +div.highlight .-Color[class*=-C168] { + color: #D75F87 +} + +div.highlight .-Color[class*=-BGC168] { + background-color: #D75F87 +} + +div.highlight .-Color[class*=-C169] { + color: #D75FAF +} + +div.highlight .-Color[class*=-BGC169] { + background-color: #D75FAF +} + +div.highlight .-Color[class*=-C170] { + color: #D75FD7 +} + +div.highlight .-Color[class*=-BGC170] { + background-color: #D75FD7 +} + +div.highlight .-Color[class*=-C171] { + color: #D75FFF +} + +div.highlight .-Color[class*=-BGC171] { + background-color: #D75FFF +} + +div.highlight .-Color[class*=-C172] { + color: #D78700 +} + +div.highlight .-Color[class*=-BGC172] { + background-color: #D78700 +} + +div.highlight .-Color[class*=-C173] { + color: #D7875F +} + +div.highlight .-Color[class*=-BGC173] { + background-color: #D7875F +} + +div.highlight .-Color[class*=-C174] { + color: #D78787 +} + +div.highlight .-Color[class*=-BGC174] { + background-color: #D78787 +} + +div.highlight .-Color[class*=-C175] { + color: #D787AF +} + +div.highlight .-Color[class*=-BGC175] { + background-color: #D787AF +} + +div.highlight .-Color[class*=-C176] { + color: #D787D7 +} + +div.highlight .-Color[class*=-BGC176] { + background-color: #D787D7 +} + +div.highlight .-Color[class*=-C177] { + color: #D787FF +} + +div.highlight .-Color[class*=-BGC177] { + background-color: #D787FF +} + +div.highlight .-Color[class*=-C178] { + color: #D7AF00 +} + +div.highlight .-Color[class*=-BGC178] { + background-color: #D7AF00 +} + +div.highlight .-Color[class*=-C179] { + color: #D7AF5F +} + +div.highlight .-Color[class*=-BGC179] { + background-color: #D7AF5F +} + +div.highlight .-Color[class*=-C180] { + color: #D7AF87 +} + +div.highlight .-Color[class*=-BGC180] { + background-color: #D7AF87 +} + +div.highlight .-Color[class*=-C181] { + color: #D7AFAF +} + +div.highlight .-Color[class*=-BGC181] { + background-color: #D7AFAF +} + +div.highlight .-Color[class*=-C182] { + color: #D7AFD7 +} + +div.highlight .-Color[class*=-BGC182] { + background-color: #D7AFD7 +} + +div.highlight .-Color[class*=-C183] { + color: #D7AFFF +} + +div.highlight .-Color[class*=-BGC183] { + background-color: #D7AFFF +} + +div.highlight .-Color[class*=-C184] { + color: #D7D700 +} + +div.highlight .-Color[class*=-BGC184] { + background-color: #D7D700 +} + +div.highlight .-Color[class*=-C185] { + color: #D7D75F +} + +div.highlight .-Color[class*=-BGC185] { + background-color: #D7D75F +} + +div.highlight .-Color[class*=-C186] { + color: #D7D787 +} + +div.highlight .-Color[class*=-BGC186] { + background-color: #D7D787 +} + +div.highlight .-Color[class*=-C187] { + color: #D7D7AF +} + +div.highlight .-Color[class*=-BGC187] { + background-color: #D7D7AF +} + +div.highlight .-Color[class*=-C188] { + color: #D7D7D7 +} + +div.highlight .-Color[class*=-BGC188] { + background-color: #D7D7D7 +} + +div.highlight .-Color[class*=-C189] { + color: #D7D7FF +} + +div.highlight .-Color[class*=-BGC189] { + background-color: #D7D7FF +} + +div.highlight .-Color[class*=-C190] { + color: #D7FF00 +} + +div.highlight .-Color[class*=-BGC190] { + background-color: #D7FF00 +} + +div.highlight .-Color[class*=-C191] { + color: #D7FF5F +} + +div.highlight .-Color[class*=-BGC191] { + background-color: #D7FF5F +} + +div.highlight .-Color[class*=-C192] { + color: #D7FF87 +} + +div.highlight .-Color[class*=-BGC192] { + background-color: #D7FF87 +} + +div.highlight .-Color[class*=-C193] { + color: #D7FFAF +} + +div.highlight .-Color[class*=-BGC193] { + background-color: #D7FFAF +} + +div.highlight .-Color[class*=-C194] { + color: #D7FFD7 +} + +div.highlight .-Color[class*=-BGC194] { + background-color: #D7FFD7 +} + +div.highlight .-Color[class*=-C195] { + color: #D7FFFF +} + +div.highlight .-Color[class*=-BGC195] { + background-color: #D7FFFF +} + +div.highlight .-Color[class*=-C196] { + color: #FF0000 +} + +div.highlight .-Color[class*=-BGC196] { + background-color: #FF0000 +} + +div.highlight .-Color[class*=-C197] { + color: #FF005F +} + +div.highlight .-Color[class*=-BGC197] { + background-color: #FF005F +} + +div.highlight .-Color[class*=-C198] { + color: #FF0087 +} + +div.highlight .-Color[class*=-BGC198] { + background-color: #FF0087 +} + +div.highlight .-Color[class*=-C199] { + color: #FF00AF +} + +div.highlight .-Color[class*=-BGC199] { + background-color: #FF00AF +} + +div.highlight .-Color[class*=-C200] { + color: #FF00D7 +} + +div.highlight .-Color[class*=-BGC200] { + background-color: #FF00D7 +} + +div.highlight .-Color[class*=-C201] { + color: #FF00FF +} + +div.highlight .-Color[class*=-BGC201] { + background-color: #FF00FF +} + +div.highlight .-Color[class*=-C202] { + color: #FF5F00 +} + +div.highlight .-Color[class*=-BGC202] { + background-color: #FF5F00 +} + +div.highlight .-Color[class*=-C203] { + color: #FF5F5F +} + +div.highlight .-Color[class*=-BGC203] { + background-color: #FF5F5F +} + +div.highlight .-Color[class*=-C204] { + color: #FF5F87 +} + +div.highlight .-Color[class*=-BGC204] { + background-color: #FF5F87 +} + +div.highlight .-Color[class*=-C205] { + color: #FF5FAF +} + +div.highlight .-Color[class*=-BGC205] { + background-color: #FF5FAF +} + +div.highlight .-Color[class*=-C206] { + color: #FF5FD7 +} + +div.highlight .-Color[class*=-BGC206] { + background-color: #FF5FD7 +} + +div.highlight .-Color[class*=-C207] { + color: #FF5FFF +} + +div.highlight .-Color[class*=-BGC207] { + background-color: #FF5FFF +} + +div.highlight .-Color[class*=-C208] { + color: #FF8700 +} + +div.highlight .-Color[class*=-BGC208] { + background-color: #FF8700 +} + +div.highlight .-Color[class*=-C209] { + color: #FF875F +} + +div.highlight .-Color[class*=-BGC209] { + background-color: #FF875F +} + +div.highlight .-Color[class*=-C210] { + color: #FF8787 +} + +div.highlight .-Color[class*=-BGC210] { + background-color: #FF8787 +} + +div.highlight .-Color[class*=-C211] { + color: #FF87AF +} + +div.highlight .-Color[class*=-BGC211] { + background-color: #FF87AF +} + +div.highlight .-Color[class*=-C212] { + color: #FF87D7 +} + +div.highlight .-Color[class*=-BGC212] { + background-color: #FF87D7 +} + +div.highlight .-Color[class*=-C213] { + color: #FF87FF +} + +div.highlight .-Color[class*=-BGC213] { + background-color: #FF87FF +} + +div.highlight .-Color[class*=-C214] { + color: #FFAF00 +} + +div.highlight .-Color[class*=-BGC214] { + background-color: #FFAF00 +} + +div.highlight .-Color[class*=-C215] { + color: #FFAF5F +} + +div.highlight .-Color[class*=-BGC215] { + background-color: #FFAF5F +} + +div.highlight .-Color[class*=-C216] { + color: #FFAF87 +} + +div.highlight .-Color[class*=-BGC216] { + background-color: #FFAF87 +} + +div.highlight .-Color[class*=-C217] { + color: #FFAFAF +} + +div.highlight .-Color[class*=-BGC217] { + background-color: #FFAFAF +} + +div.highlight .-Color[class*=-C218] { + color: #FFAFD7 +} + +div.highlight .-Color[class*=-BGC218] { + background-color: #FFAFD7 +} + +div.highlight .-Color[class*=-C219] { + color: #FFAFFF +} + +div.highlight .-Color[class*=-BGC219] { + background-color: #FFAFFF +} + +div.highlight .-Color[class*=-C220] { + color: #FFD700 +} + +div.highlight .-Color[class*=-BGC220] { + background-color: #FFD700 +} + +div.highlight .-Color[class*=-C221] { + color: #FFD75F +} + +div.highlight .-Color[class*=-BGC221] { + background-color: #FFD75F +} + +div.highlight .-Color[class*=-C222] { + color: #FFD787 +} + +div.highlight .-Color[class*=-BGC222] { + background-color: #FFD787 +} + +div.highlight .-Color[class*=-C223] { + color: #FFD7AF +} + +div.highlight .-Color[class*=-BGC223] { + background-color: #FFD7AF +} + +div.highlight .-Color[class*=-C224] { + color: #FFD7D7 +} + +div.highlight .-Color[class*=-BGC224] { + background-color: #FFD7D7 +} + +div.highlight .-Color[class*=-C225] { + color: #FFD7FF +} + +div.highlight .-Color[class*=-BGC225] { + background-color: #FFD7FF +} + +div.highlight .-Color[class*=-C226] { + color: #FFFF00 +} + +div.highlight .-Color[class*=-BGC226] { + background-color: #FFFF00 +} + +div.highlight .-Color[class*=-C227] { + color: #FFFF5F +} + +div.highlight .-Color[class*=-BGC227] { + background-color: #FFFF5F +} + +div.highlight .-Color[class*=-C228] { + color: #FFFF87 +} + +div.highlight .-Color[class*=-BGC228] { + background-color: #FFFF87 +} + +div.highlight .-Color[class*=-C229] { + color: #FFFFAF +} + +div.highlight .-Color[class*=-BGC229] { + background-color: #FFFFAF +} + +div.highlight .-Color[class*=-C230] { + color: #FFFFD7 +} + +div.highlight .-Color[class*=-BGC230] { + background-color: #FFFFD7 +} + +div.highlight .-Color[class*=-C231] { + color: #FFFFFF +} + +div.highlight .-Color[class*=-BGC231] { + background-color: #FFFFFF +} + +div.highlight .-Color[class*=-C232] { + color: #080808 +} + +div.highlight .-Color[class*=-BGC232] { + background-color: #080808 +} + +div.highlight .-Color[class*=-C233] { + color: #121212 +} + +div.highlight .-Color[class*=-BGC233] { + background-color: #121212 +} + +div.highlight .-Color[class*=-C234] { + color: #1C1C1C +} + +div.highlight .-Color[class*=-BGC234] { + background-color: #1C1C1C +} + +div.highlight .-Color[class*=-C235] { + color: #262626 +} + +div.highlight .-Color[class*=-BGC235] { + background-color: #262626 +} + +div.highlight .-Color[class*=-C236] { + color: #303030 +} + +div.highlight .-Color[class*=-BGC236] { + background-color: #303030 +} + +div.highlight .-Color[class*=-C237] { + color: #3A3A3A +} + +div.highlight .-Color[class*=-BGC237] { + background-color: #3A3A3A +} + +div.highlight .-Color[class*=-C238] { + color: #444444 +} + +div.highlight .-Color[class*=-BGC238] { + background-color: #444444 +} + +div.highlight .-Color[class*=-C239] { + color: #4E4E4E +} + +div.highlight .-Color[class*=-BGC239] { + background-color: #4E4E4E +} + +div.highlight .-Color[class*=-C240] { + color: #585858 +} + +div.highlight .-Color[class*=-BGC240] { + background-color: #585858 +} + +div.highlight .-Color[class*=-C241] { + color: #626262 +} + +div.highlight .-Color[class*=-BGC241] { + background-color: #626262 +} + +div.highlight .-Color[class*=-C242] { + color: #6C6C6C +} + +div.highlight .-Color[class*=-BGC242] { + background-color: #6C6C6C +} + +div.highlight .-Color[class*=-C243] { + color: #767676 +} + +div.highlight .-Color[class*=-BGC243] { + background-color: #767676 +} + +div.highlight .-Color[class*=-C244] { + color: #808080 +} + +div.highlight .-Color[class*=-BGC244] { + background-color: #808080 +} + +div.highlight .-Color[class*=-C245] { + color: #8A8A8A +} + +div.highlight .-Color[class*=-BGC245] { + background-color: #8A8A8A +} + +div.highlight .-Color[class*=-C246] { + color: #949494 +} + +div.highlight .-Color[class*=-BGC246] { + background-color: #949494 +} + +div.highlight .-Color[class*=-C247] { + color: #9E9E9E +} + +div.highlight .-Color[class*=-BGC247] { + background-color: #9E9E9E +} + +div.highlight .-Color[class*=-C248] { + color: #A8A8A8 +} + +div.highlight .-Color[class*=-BGC248] { + background-color: #A8A8A8 +} + +div.highlight .-Color[class*=-C249] { + color: #B2B2B2 +} + +div.highlight .-Color[class*=-BGC249] { + background-color: #B2B2B2 +} + +div.highlight .-Color[class*=-C250] { + color: #BCBCBC +} + +div.highlight .-Color[class*=-BGC250] { + background-color: #BCBCBC +} + +div.highlight .-Color[class*=-C251] { + color: #C6C6C6 +} + +div.highlight .-Color[class*=-BGC251] { + background-color: #C6C6C6 +} + +div.highlight .-Color[class*=-C252] { + color: #D0D0D0 +} + +div.highlight .-Color[class*=-BGC252] { + background-color: #D0D0D0 +} + +div.highlight .-Color[class*=-C253] { + color: #DADADA +} + +div.highlight .-Color[class*=-BGC253] { + background-color: #DADADA +} + +div.highlight .-Color[class*=-C254] { + color: #E4E4E4 +} + +div.highlight .-Color[class*=-BGC254] { + background-color: #E4E4E4 +} + +div.highlight .-Color[class*=-C255] { + color: #EEEEEE +} + +div.highlight .-Color[class*=-BGC255] { + background-color: #EEEEEE +} diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 000000000..7107cec93 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 000000000..84ab3030a --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #666666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #0000FF } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 000000000..92da3f8b2 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,619 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlinks", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + let score = Math.round(100 * queryLower.length / title.length) + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/sphinx_lesson.css b/_static/sphinx_lesson.css new file mode 100644 index 000000000..14b20c644 --- /dev/null +++ b/_static/sphinx_lesson.css @@ -0,0 +1,51 @@ +/* sphinx_lesson.css */ + +body.wy-body-for-nav img.with-border { + border: 2px solid; +} + +.rst-content .admonition-no-content { + padding-bottom: 0px; +} + +.rst-content .demo > .admonition-title::before { + content: "\01F440"; /* Eyes */ } +.rst-content .type-along > .admonition-title::before { + content: "\02328\0FE0F"; /* Keyboard */ } +.rst-content .exercise > .admonition-title::before { + content: "\0270D\0FE0F"; /* Hand */ } +.rst-content .solution > .admonition-title::before { + content: "\02714\0FE0E"; /* Check mark */ } +.rst-content .homework > .admonition-title::before { + content: "\01F4DD"; /* Memo */ } +.rst-content .discussion > .admonition-title::before { + content: "\01F4AC"; /* Speech balloon */ } +.rst-content .questions > .admonition-title::before { + content: "\02753\0FE0E"; /* Question mark */ } +.rst-content .prerequisites > .admonition-title::before { + content: "\02699"; /* Gear */ } +.rst-content .seealso > .admonition-title::before { + content: "\027A1\0FE0E"; /* Question mark */ } + + +/* instructor-note */ +.rst-content .instructor-note { + background: #e7e7e7; +} +.rst-content .instructor-note > .admonition-title { + background: #6a6a6a; +} +.rst-content .instructor-note > .admonition-title::before { + content: ""; +} + + +/* sphinx_toggle_button, make the font white */ +.rst-content .toggle.admonition button.toggle-button { + color: white; +} + +/* sphinx-togglebutton, remove underflow when toggled to hidden mode */ +.rst-content .admonition.toggle-hidden { + padding-bottom: 0px; +} diff --git a/_static/tabs.css b/_static/tabs.css new file mode 100644 index 000000000..957ba60d6 --- /dev/null +++ b/_static/tabs.css @@ -0,0 +1,89 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: #1D5C87; + line-height: 24px; + margin: 0; + font-size: 16px; + font-weight: 400; + background-color: rgba(255, 255, 255, 0); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid white; + margin: -1px; + background-color: white; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: white; +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24 px; +} + +/* Dark theme preference styling */ + +@media (prefers-color-scheme: dark) { + body[data-theme="auto"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); + } + + body[data-theme="auto"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); + } + + body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 1px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); + } +} + +/* Explicit dark theme styling */ + +body[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +body[data-theme="dark"] .sphinx-tabs-tab { + color: white; + background-color: rgba(255, 255, 255, 0.05); +} + +body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} diff --git a/_static/tabs.js b/_static/tabs.js new file mode 100644 index 000000000..48dc303c8 --- /dev/null +++ b/_static/tabs.js @@ -0,0 +1,145 @@ +try { + var session = window.sessionStorage || {}; +} catch (e) { + var session = {}; +} + +window.addEventListener("DOMContentLoaded", () => { + const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); + const tabLists = document.querySelectorAll('[role="tablist"]'); + + allTabs.forEach(tab => { + tab.addEventListener("click", changeTabs); + }); + + tabLists.forEach(tabList => { + tabList.addEventListener("keydown", keyTabs); + }); + + // Restore group tab selection from session + const lastSelected = session.getItem('sphinx-tabs-last-selected'); + if (lastSelected != null) selectNamedTabs(lastSelected); +}); + +/** + * Key focus left and right between sibling elements using arrows + * @param {Node} e the element in focus when key was pressed + */ +function keyTabs(e) { + const tab = e.target; + let nextTab = null; + if (e.keyCode === 39 || e.keyCode === 37) { + tab.setAttribute("tabindex", -1); + // Move right + if (e.keyCode === 39) { + nextTab = tab.nextElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.firstElementChild; + } + // Move left + } else if (e.keyCode === 37) { + nextTab = tab.previousElementSibling; + if (nextTab === null) { + nextTab = tab.parentNode.lastElementChild; + } + } + } + + if (nextTab !== null) { + nextTab.setAttribute("tabindex", 0); + nextTab.focus(); + } +} + +/** + * Select or deselect clicked tab. If a group tab + * is selected, also select tab in other tabLists. + * @param {Node} e the element that was clicked + */ +function changeTabs(e) { + // Use this instead of the element that was clicked, in case it's a child + const notSelected = this.getAttribute("aria-selected") === "false"; + const positionBefore = this.parentNode.getBoundingClientRect().top; + const notClosable = !this.parentNode.classList.contains("closeable"); + + deselectTabList(this); + + if (notSelected || notClosable) { + selectTab(this); + const name = this.getAttribute("name"); + selectNamedTabs(name, this.id); + + if (this.classList.contains("group-tab")) { + // Persist during session + session.setItem('sphinx-tabs-last-selected', name); + } + } + + const positionAfter = this.parentNode.getBoundingClientRect().top; + const positionDelta = positionAfter - positionBefore; + // Scroll to offset content resizing + window.scrollTo(0, window.scrollY + positionDelta); +} + +/** + * Select tab and show associated panel. + * @param {Node} tab tab to select + */ +function selectTab(tab) { + tab.setAttribute("aria-selected", true); + + // Show the associated panel + document + .getElementById(tab.getAttribute("aria-controls")) + .removeAttribute("hidden"); +} + +/** + * Hide the panels associated with all tabs within the + * tablist containing this tab. + * @param {Node} tab a tab within the tablist to deselect + */ +function deselectTabList(tab) { + const parent = tab.parentNode; + const grandparent = parent.parentNode; + + Array.from(parent.children) + .forEach(t => t.setAttribute("aria-selected", false)); + + Array.from(grandparent.children) + .slice(1) // Skip tablist + .forEach(panel => panel.setAttribute("hidden", true)); +} + +/** + * Select grouped tabs with the same name, but no the tab + * with the given id. + * @param {Node} name name of grouped tab to be selected + * @param {Node} clickedId id of clicked tab + */ +function selectNamedTabs(name, clickedId=null) { + const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); + const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); + + tabLists + .forEach(tabList => { + // Don't want to change the tabList containing the clicked tab + const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); + if (clickedTab === null ) { + // Select first tab with matching name + const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); + deselectTabList(tab); + selectTab(tab); + } + }) +} + +if (typeof exports === 'undefined') { + exports = {}; +} + +exports.keyTabs = keyTabs; +exports.changeTabs = changeTabs; +exports.selectTab = selectTab; +exports.deselectTabList = deselectTabList; +exports.selectNamedTabs = selectNamedTabs; diff --git a/_static/term_role_formatting.css b/_static/term_role_formatting.css new file mode 100644 index 000000000..0b66095c7 --- /dev/null +++ b/_static/term_role_formatting.css @@ -0,0 +1,4 @@ +/* Make terms bold */ +a.reference span.std-term { + font-weight: bold; +} diff --git a/_static/togglebutton.css b/_static/togglebutton.css new file mode 100644 index 000000000..54a678790 --- /dev/null +++ b/_static/togglebutton.css @@ -0,0 +1,160 @@ +/** + * Admonition-based toggles + */ + +/* Visibility of the target */ +.admonition.toggle .admonition-title ~ * { + transition: opacity .3s, height .3s; +} + +/* Toggle buttons inside admonitions so we see the title */ +.admonition.toggle { + position: relative; +} + +/* Titles should cut off earlier to avoid overlapping w/ button */ +.admonition.toggle .admonition-title { + padding-right: 25%; + cursor: pointer; +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:hover { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 1%); +} + +/* Hovering will cause a slight shift in color to make it feel interactive */ +.admonition.toggle .admonition-title:active { + box-shadow: inset 0 0 0px 20px rgb(0 0 0 / 3%); +} + +/* Remove extra whitespace below the admonition title when hidden */ +.admonition.toggle-hidden { + padding-bottom: 0; +} + +.admonition.toggle-hidden .admonition-title { + margin-bottom: 0; +} + +/* hides all the content of a page until de-toggled */ +.admonition.toggle-hidden .admonition-title ~ * { + height: 0; + margin: 0; + opacity: 0; + visibility: hidden; +} + +/* General button style and position*/ +button.toggle-button { + /** + * Background and shape. By default there's no background + * but users can style as they wish + */ + background: none; + border: none; + outline: none; + + /* Positioning just inside the admonition title */ + position: absolute; + right: 0.5em; + padding: 0px; + border: none; + outline: none; +} + +/* Display the toggle hint on wide screens */ +@media (min-width: 768px) { + button.toggle-button.toggle-button-hidden:before { + content: attr(data-toggle-hint); /* This will be filled in by JS */ + font-size: .8em; + align-self: center; + } +} + +/* Icon behavior */ +.tb-icon { + transition: transform .2s ease-out; + height: 1.5em; + width: 1.5em; + stroke: currentColor; /* So that we inherit the color of other text */ +} + +/* The icon should point right when closed, down when open. */ +/* Open */ +.admonition.toggle button .tb-icon { + transform: rotate(90deg); +} + +/* Closed */ +.admonition.toggle button.toggle-button-hidden .tb-icon { + transform: rotate(0deg); +} + +/* With details toggles, we don't rotate the icon so it points right */ +details.toggle-details .tb-icon { + height: 1.4em; + width: 1.4em; + margin-top: 0.1em; /* To center the button vertically */ +} + + +/** + * Details-based toggles. + * In this case, we wrap elements with `.toggle` in a details block. + */ + +/* Details blocks */ +details.toggle-details { + margin: 1em 0; +} + + +details.toggle-details summary { + display: flex; + align-items: center; + cursor: pointer; + list-style: none; + border-radius: .2em; + border-left: 3px solid #1976d2; + background-color: rgb(204 204 204 / 10%); + padding: 0.2em 0.7em 0.3em 0.5em; /* Less padding on left because the SVG has left margin */ + font-size: 0.9em; +} + +details.toggle-details summary:hover { + background-color: rgb(204 204 204 / 20%); +} + +details.toggle-details summary:active { + background: rgb(204 204 204 / 28%); +} + +.toggle-details__summary-text { + margin-left: 0.2em; +} + +details.toggle-details[open] summary { + margin-bottom: .5em; +} + +details.toggle-details[open] summary .tb-icon { + transform: rotate(90deg); +} + +details.toggle-details[open] summary ~ * { + animation: toggle-fade-in .3s ease-out; +} + +@keyframes toggle-fade-in { + from {opacity: 0%;} + to {opacity: 100%;} +} + +/* Print rules - we hide all toggle button elements at print */ +@media print { + /* Always hide the summary so the button doesn't show up */ + details.toggle-details summary { + display: none; + } +} \ No newline at end of file diff --git a/_static/togglebutton.js b/_static/togglebutton.js new file mode 100644 index 000000000..215a7eef4 --- /dev/null +++ b/_static/togglebutton.js @@ -0,0 +1,187 @@ +/** + * Add Toggle Buttons to elements + */ + +let toggleChevron = ` + + + +`; + +var initToggleItems = () => { + var itemsToToggle = document.querySelectorAll(togglebuttonSelector); + console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`) + // Add the button to each admonition and hook up a callback to toggle visibility + itemsToToggle.forEach((item, index) => { + if (item.classList.contains("admonition")) { + // If it's an admonition block, then we'll add a button inside + // Generate unique IDs for this item + var toggleID = `toggle-${index}`; + var buttonID = `button-${toggleID}`; + + item.setAttribute('id', toggleID); + if (!item.classList.contains("toggle")){ + item.classList.add("toggle"); + } + // This is the button that will be added to each item to trigger the toggle + var collapseButton = ` + `; + + title = item.querySelector(".admonition-title") + title.insertAdjacentHTML("beforeend", collapseButton); + thisButton = document.getElementById(buttonID); + + // Add click handlers for the button + admonition title (if admonition) + admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`) + if (admonitionTitle) { + // If an admonition, then make the whole title block clickable + admonitionTitle.addEventListener('click', toggleClickHandler); + admonitionTitle.dataset.target = toggleID + admonitionTitle.dataset.button = buttonID + } else { + // If not an admonition then we'll listen for the button click + thisButton.addEventListener('click', toggleClickHandler); + } + + // Now hide the item for this toggle button unless explicitly noted to show + if (!item.classList.contains("toggle-shown")) { + toggleHidden(thisButton); + } + } else { + // If not an admonition, wrap the block in a
block + // Define the structure of the details block and insert it as a sibling + var detailsBlock = ` +
+ + ${toggleChevron} + ${toggleHintShow} + +
`; + item.insertAdjacentHTML("beforebegin", detailsBlock); + + // Now move the toggle-able content inside of the details block + details = item.previousElementSibling + details.appendChild(item) + item.classList.add("toggle-details__container") + + // Set up a click trigger to change the text as needed + details.addEventListener('click', (click) => { + let parent = click.target.parentElement; + if (parent.tagName.toLowerCase() == "details") { + summary = parent.querySelector("summary"); + details = parent; + } else { + summary = parent; + details = parent.parentElement; + } + // Update the inner text for the proper hint + if (details.open) { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow; + } else { + summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide; + } + + }); + + // If we have a toggle-shown class, open details block should be open + if (item.classList.contains("toggle-shown")) { + details.click(); + } + } + }) +}; + +// This should simply add / remove the collapsed class and change the button text +var toggleHidden = (button) => { + target = button.dataset['target'] + var itemToToggle = document.getElementById(target); + if (itemToToggle.classList.contains("toggle-hidden")) { + itemToToggle.classList.remove("toggle-hidden"); + button.classList.remove("toggle-button-hidden"); + } else { + itemToToggle.classList.add("toggle-hidden"); + button.classList.add("toggle-button-hidden"); + } +} + +var toggleClickHandler = (click) => { + // Be cause the admonition title is clickable and extends to the whole admonition + // We only look for a click event on this title to trigger the toggle. + + if (click.target.classList.contains("admonition-title")) { + button = click.target.querySelector(".toggle-button"); + } else if (click.target.classList.contains("tb-icon")) { + // We've clicked the icon and need to search up one parent for the button + button = click.target.parentElement; + } else if (click.target.tagName == "polyline") { + // We've clicked the SVG elements inside the button, need to up 2 layers + button = click.target.parentElement.parentElement; + } else if (click.target.classList.contains("toggle-button")) { + // We've clicked the button itself and so don't need to do anything + button = click.target; + } else { + console.log(`[togglebutton]: Couldn't find button for ${click.target}`) + } + target = document.getElementById(button.dataset['button']); + toggleHidden(target); +} + +// If we want to blanket-add toggle classes to certain cells +var addToggleToSelector = () => { + const selector = ""; + if (selector.length > 0) { + document.querySelectorAll(selector).forEach((item) => { + item.classList.add("toggle"); + }) + } +} + +// Helper function to run when the DOM is finished +const sphinxToggleRunWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} +sphinxToggleRunWhenDOMLoaded(addToggleToSelector) +sphinxToggleRunWhenDOMLoaded(initToggleItems) + +/** Toggle details blocks to be open when printing */ +if (toggleOpenOnPrint == "true") { + window.addEventListener("beforeprint", () => { + // Open the details + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.dataset["togglestatus"] = el.open; + el.open = true; + }); + + // Open the admonitions + document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => { + console.log(el); + el.querySelector("button.toggle-button").click(); + el.dataset["toggle_after_print"] = "true"; + }); + }); + window.addEventListener("afterprint", () => { + // Re-close the details that were closed + document.querySelectorAll("details.toggle-details").forEach((el) => { + el.open = el.dataset["togglestatus"] == "true"; + delete el.dataset["togglestatus"]; + }); + + // Re-close the admonition toggle buttons + document.querySelectorAll(".admonition.toggle").forEach((el) => { + if (el.dataset["toggle_after_print"] == "true") { + el.querySelector("button.toggle-button").click(); + delete el.dataset["toggle_after_print"]; + } + }); + }); +} diff --git a/changelog.html b/changelog.html new file mode 100644 index 000000000..bd8cf8d17 --- /dev/null +++ b/changelog.html @@ -0,0 +1,613 @@ + + + + + + + Changelog — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Changelog

+
+

8.20.0

+
    +
  • tab for displaying local sessions and their respective status

  • +
  • additional task parameters for passiveChoiceWorld

  • +
  • work on making the GUI code more modular

  • +
+
+
+

8.19.6

+
    +
  • hotfix: fix race-condition that caused scrambled online-plots

  • +
+
+
+

8.19.5

+
    +
  • hotfix: move serial validation from SerialSingleton to Serial

  • +
+
+
+

8.19.4

+
    +
  • hotfix: fix validation for Alyx when no Alyx URL has been set

  • +
  • hotfix: fix validation for Bpod HiFi module

  • +
  • adapted update instructions in update notification & documentation

  • +
+
+
+

8.19.3

+
    +
  • hotfix: force stimulus to freeze in center of screen during “freeze_reward” state

  • +
  • method for copying snapshots to the local server using the SessionCopier

  • +
  • documentation for transition to Bpod HiFi

  • +
+
+
+

8.19.2

+
    +
  • hotfix: only register water administrations once per protocol

  • +
  • hotfix: reverse wheel contingency now controlled through task parameter STIM_REVERSE

  • +
+
+
+

8.19.1

+
    +
  • hotfix: threading warnings during valve calibration (when used without scale)

  • +
  • hotfix: unreliable exit condition for state machine during valve calibration

  • +
+
+
+

8.19.0

+
    +
  • automated validation of rig components

  • +
  • adaptive reward parameter for trainingPhaseChoiceWorld

  • +
  • add validate_video entry-point

  • +
  • switch from flake8 to ruff for linting & code-checks

  • +
  • automatically set correct trigger-mode when setting up the cameras

  • +
  • support rotary encoder on arbitrary module port

  • +
  • add ambient sensor reading back to trial log

  • +
  • allow negative stimulus gain (reverse wheel contingency)

  • +
+
+
+
+

8.18.0

+
    +
  • valve calibration routine

  • +
+
+
+
+

8.17.0

+
    +
  • consolidated data transfer routine across all rig computers

  • +
  • new video workflow with support for multiple named camera setups

  • +
  • various small fixes, work on documentation, unit-tests

  • +
+
+
+
+

8.16.1

+
    +
  • Hoferlab: when bpod returns inconsistent error, time-out or correct, throw the exception after logging

  • +
  • add AMP_TYPE field to hardware_settings.yaml (device_sound) to handle the combination of HiFi module and AMP2x15 amplifier

  • +
+
+
+

8.16.0

+
    +
  • Support for Bpod HiFi Module

  • +
  • Support for Zapit Optostim (NM)

  • +
  • more robust handling of Bpod’s serial messages: iblrig.hardware._define_message

  • +
+
+
+
+

8.15.6

+
    +
  • Task specifications: The time from the stimulus offset to the quiescence period is targeted to 1 second instead of 1.5 seconds

  • +
  • Task specifications: The correct delay time starts running from the start of the reward state, not the end of the reward state.

  • +
  • Fixed unit-tests

  • +
+
+
+

8.15.5

+
    +
  • hotfix: show Garbor patch in passive choice-world, GUI option for session ID, no dud detection

  • +
+
+
+

8.15.4

+
    +
  • hotfix: disable prompt for deleting “duds” for appended sessions

  • +
+
+
+

8.15.3

+
    +
  • hotfix: don’t wait for microphone workflow to finish

  • +
+
+
+

8.15.2

+
    +
  • hotfix: pin iblutil to >=1.7.4 to address unicode encoding issue during logging

  • +
  • hotfix: allow pass with warning in case where lab validation fails due to Alyx down / server issues

  • +
  • change: use QT workers for Frame2TTL calibration steps

  • +
  • extra task parameters: support list of strings

  • +
  • frame2ttl: raise exception on incorrect port setting

  • +
  • convert_ui: add argument for filename glob

  • +
+
+
+

8.15.1

+
    +
  • hotfix: correct parsing of description files and ignore junk sessions in iterate_protocols

  • +
+
+
+

8.15.0

+
    +
  • feature: calibration routine for frame2ttl v1-3 in Tools menu

  • +
  • feature: debug-flag for IBLRIG Wizard

  • +
+
+
+
+

8.14.2

+
    +
  • hotfix: wrong return-type in _iterate_protocols - pt 2

  • +
+
+
+

8.14.1

+
    +
  • hotfix: wrong return-type in _iterate_protocols

  • +
+
+
+

8.14.0

+
    +
  • show dialog boxes and plots for appended sessions

  • +
+
+
+
+

8.13.5

+
    +
  • make sure unused arguments passed up to BaseChoiceWorld do not crash the task (example delay_secs in passiveChoiceWorld)

  • +
+
+
+

8.13.4

+
    +
  • pin iblutil to version 1.7.3 or later

  • +
  • reworked upgrade script and moved to separate file to avoid file-access issues

  • +
  • fixed display of version string in “about” tab

  • +
  • revert logging of task events to GUI only

  • +
+
+
+

8.13.3

+
    +
  • add tests with mock Bonsai to cover for task start methods

  • +
  • hotfix: also log to PowerShell (for now)

  • +
+
+
+

8.13.2

+
    +
  • hotfix: ‘WindowsPath’ object has no attribute ‘split’

  • +
+
+
+

8.13.1

+
    +
  • hotfix: passing non-existent parameter to Bonsai workflow

  • +
+
+
+

8.13.0

+
    +
  • restructured user interface

  • +
  • script for starting video-session in ephys-rig

  • +
  • installer scripts for Spinnaker SDK / PySpin

  • +
  • validated parsing of settings files

  • +
  • added legend to trials-timeline

  • +
  • added button for triggering a free reward (only available outside of running task for now)

  • +
  • cleaned-up logging

  • +
  • various improvements under the hood, clean-up and unit-tests

  • +
+
+
+
+

8.12.13

+
    +
  • fix problem with corrupt acquisition descriptions in history

  • +
+
+
+

8.12.12

+
    +
  • skipped

  • +
+
+
+

8.12.11

+
    +
  • hotfix for creation of bonsai layout-file

  • +
  • separated installers for Spinnaker SDK and PySpin

  • +
+
+
+

8.12.10

+
    +
  • ignore user-side changes to bonsai layouts (for camera workflows only)

  • +
  • error message if rig-name is not defined in Alyx

  • +
  • populate delegate users

  • +
  • the usual: minor fixes, clean-ups and unit-tests

  • +
+
+
+

8.12.9

+
    +
  • usability improvements for “Show Training Level” tool

  • +
  • ignore unused behavior ports

  • +
  • remove unnecessary dependencies

  • +
+
+
+

8.12.8

+
    +
  • fix incorrect limits & unit for adaptive gain in trainingChoiceWorld

  • +
  • usability improvements for “Show Training Level” tool

  • +
+
+
+

8.12.7

+
    +
  • online plot: fix line colors and add legends

  • +
  • do not show Bonsai editor during session

  • +
+
+
+

8.12.6

+
    +
  • reverting TTL on trial end introduced with PR #504, release 8.9.0

  • +
  • general code maintenance (unit-tests, doc-strings, type-hints, removal of dead code)

  • +
+
+
+

8.12.5

+
    +
  • add a tools menu in the wizard to get training level from v7 sessions to ease transition

  • +
+
+
+

8.12.4

+
    +
  • updated online-plots

  • +
+
+
+

8.12.3

+
    +
  • bugfix: getting training status of subject not present on local server

  • +
  • skipping of bpod initialization now optional (used in GUI)

  • +
  • disable button for status LED if not supported by hardware

  • +
  • tests, type-hints, removal of dead code

  • +
+
+
+

8.12.2

+
    +
  • bugfix: rollback skipping of bpod initialization (possible source of integer overflow)

  • +
  • removal of dead code

  • +
+
+
+

8.12.1

+
    +
  • bugfix: remember ability for setting the status LED

  • +
+
+
+

8.12.0

+
    +
  • add a trainingPhaseChoiceWorld task to fix the training levels

  • +
  • bugfix: copy script prompt accepts both upper case and lower case Y to proceed

  • +
  • bugfix: update-check used incorrect calls for subprocesses

  • +
+
+
+
+

8.11.5

+
    +
  • bugfix: negative time being displayed in the live-plots

  • +
+
+
+

8.11.4

+
    +
  • bugfix: incorrect subprocess-calls in version_management

  • +
+
+
+

8.11.3

+
    +
  • bugfix: 0 contrasts argument overwritten for trainingCW

  • +
+
+
+

8.11.2

+
    +
  • make custom_tasks optional

  • +
  • repair lost entry-point for iblrig wizard

  • +
  • fetch remote tags only if connected to internet

  • +
+
+
+

8.11.1

+
    +
  • add GUI options for AdvancedChoiceWorld

  • +
+
+
+

8.11.0

+
    +
  • add check for availability of internet

  • +
  • add proper CLI for data transfer scripts

  • +
  • add control for disabling Bpod status LED

  • +
  • skip initialization of existing Bpod singleton

  • +
  • remember settings for status LED and GUI position

  • +
  • move update-check to separate thread

  • +
  • detect duds (less than 42 trials) and offer deletion

  • +
  • various small bugfixes

  • +
+
+
+
+

8.10.2

+
    +
  • hot-fix parsing of path args in transfer_data

  • +
  • add install_spinnaker command for … installing spinnaker

  • +
  • fixed CI warnings about ports that haven’t been closed

  • +
  • draw subject weight for adaptive reward from previous session

  • +
  • format reward with 1 decimal on online plot

  • +
+
+
+

8.10.1

+
    +
  • more reliable way to check for dirty repository

  • +
  • add visual hint for unfilled list-views

  • +
+
+
+

8.10.0

+
    +
  • adaptive reward from previous sessions in TrainingChoiceWorld

  • +
  • updater: fetch remote changelog to advertise new features

  • +
+
+
+
+

8.9.4

+
    +
  • correction for version regex

  • +
  • fix version strings for compatibility with packaging.version

  • +
+
+
+

8.9.3

+
    +
  • re-implemented update notice

  • +
  • corrected implementation of end session criteria

  • +
  • set adaptive reward to false temporarily

  • +
+
+
+

8.9.2

+
    +
  • hot-fix for disabling the update-check - this will need work

  • +
+
+
+

8.9.1

+
    +
  • hot-fix for missing live-plots

  • +
+
+
+

8.9.0

+
    +
  • major rework of the GUI

  • +
  • task-specific settings

  • +
  • new dialogs for weight & droppings

  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/faq.html b/faq.html new file mode 100644 index 000000000..1c8ad862a --- /dev/null +++ b/faq.html @@ -0,0 +1,267 @@ + + + + + + + Frequently Asked Questions — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Frequently Asked Questions

+

Here we collect common issues and questions regarding IBLRIG.

+
+

First Aid

+

If your rig is acting up:

+
    +
  • Employ the automated test-script bundled with IBLRIG. This script helps identify common configuration issues. +Execute it using PowerShell:

    +
    C:\iblrigv8\venv\scripts\Activate.ps1
    +validate_iblrig
    +
    +
    +
  • +
  • Check the comprehensive user manual (“Appendix 3” on GoogleDrive). +Verify if all connections are secure, and configurations align with the manual’s guidelines.

  • +
  • Don’t hesitate to contact our developer team for assistance. We’re committed to getting your system back on track.

  • +
+
+
+

Bug Reports & Feature Requests

+

IBLRIG remains in dynamic development. Your input is invaluable in shaping its direction. Send us your +bug reports and feature-requests via GitHub - we will do our best to help you.

+
+
+

Sound Issues

+
    +
  • Double-check all wiring for loose connections.

  • +
  • Is hardware_settings.yaml set up correctly? Valid options for sound OUTPUT are:

    +
      +
    • harp,

    • +
    • xonar, or

    • +
    • sysdefault.

    • +
    +

    Make sure that this value matches the actual soundcard used on your rig.

    +
  • +
+
+
+

Screen Issues

+
+

General

+
    +
  • The ribbon cable attaching the screen to the driver board is notoriously finicky. If you are having brightness issues or do not have a signal, try gently repositioning this cable and ensure it is tightly seated in its connection.

  • +
  • Screen and ribbon cable can be easily damaged. It is useful to have backup at hand.

  • +
  • Screen flashing can occur if the power supply does not match the screen specifications. Use a 12V adapter with at least 1A.

  • +
  • If the Bonsai display is appearing on the PC screen when a task starts, try unplugging the rig screen, rebooting and plugging the screen back in. Other variations of screen unplugging and rebooting may also work. +Also make sure, that the DISPLAY_IDX value in hardware_settings.yaml is set correctly.

  • +
+
+
+

Defining Default Position & Size of Bonsai Visualizers

+

Is the preview window of the video recording showing on the iPad screen instead of the computer’s main display during a +session? To redefine the default position and size of the Bonsai visualizer:

+
    +
  1. Open the Bonsai executable distributed with IBLRIG: C:\iblrigv8\Bonsai\Bonsai.exe.

  2. +
  3. Open the respective Bonsai workflow:

    +
    C:\iblrigv8\devices\camera_recordings\TrainingRig_SaveVideo_TrainingTasks.bonsai
    +
    +
    +
  4. +
  5. Start the workflow by clicking on the play-button.

  6. +
  7. Adjust the position and size of the windows as per your preference.

  8. +
  9. Stop the workflow.

  10. +
  11. Save the workflow.

  12. +
+
+
+
+

Camera Issues

+
    +
  • If a camera is not detected by the computer or causes intermittent issues it might be an issue with the USB connection.

    +
      +
    • Ensure that the camera is connected to the computer on a USB3 port (usually indicated by a blue plastic tab in the port). +USB2 (black tabs) neither provides the necessary transfer rates nor sufficient current to power the camera.

    • +
    • Use the original USB3.1 cable provided by FLIR. +It comes in 3 m or 5 m - stick with the shorter version if possible.

    • +
    • Try to avoid USB extensions. +The original cable (see above) should be sufficiently long in most situations.

    • +
    • Ideally, use one of the onboard USB3 ports of your computer facing to the back of the machine. +Front-facing ports may not be able to provide enough power.

    • +
    • If you use a USB 3.1 Host Controller Card check if it requires additional powering through a SATA or Molex cable. +FLIR offers a few models that should work fine.

    • +
    +
  • +
+
+
+

Frame2TTL

+
    +
  • Version 1 of Frame2TTL won’t be detected after restarting the computer. +Unplugging and replugging the USB cable should make it responsive again.

  • +
  • If IBLRIG complains about not receiving any TTL signals from Frame2TTL:

    +
      +
    • Ensure Frame2TTL’s sensor is positioned over the bottom-right corner of the rig’s screen. +Secure the sensor’s cable to the screen mount with a zip-tie to prevent it from slipping off the screen. +Additionally, use a piece of electrical tape to hold the sensor in place.

    • +
    • Verify that the sensor is connected to Frame2TTL with the correct polarity

      +
        +
      • Version 1: GND = black cable, SIG = white cable

      • +
      • Version 2 and 3: BLK = black cable, WHT = white cable

      • +
      +
    • +
    • Ensure that Frame2TTL’s TTL Output is plugged into Bpod’s TTL Input #1. +Note that versions 2 and 3 of Frame2TTL have a second BNC output labeled “analog” - this is not the TTL output.

    • +
    • Recalibrate Frame2TTL using the calibration routine in IBLRIG’s Tools menu and check for any errors.

    • +
    +
  • +
  • If the above steps do not resolve the issue, try the following:

    +
      +
    1. Swap out the BNC cable between Frame2TTL and Bpod. +Use a single cable without any branches.

    2. +
    3. Connect an oscilloscope to the Bpod end of the cable and run a calibration. +Look for a voltage step in Frame2TTL’s output when the calibration routine switches from dark to light.

    4. +
    5. If you do see the change in the TTL signal, the Bpod might be faulty. Try using a different Bpod unit.

    6. +
    7. If you do not see the voltage step, the Frame2TTL might be faulty. Try using a different Frame2TTL unit.

    8. +
    +
  • +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 000000000..3db9b6a38 --- /dev/null +++ b/genindex.html @@ -0,0 +1,134 @@ + + + + + + Index — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/hardware.html b/hardware.html new file mode 100644 index 000000000..47299b56c --- /dev/null +++ b/hardware.html @@ -0,0 +1,240 @@ + + + + + + + Hardware Guide — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Hardware Guide

+
+

Upgrading Xonar AE to Bpod HiFi Module

+
+

Note

+

The following guide only concerns behavior rigs using Asus Xonar AE sound cards. +The Harp sound cards used in our Ephys and Mesoscope rigs work fine and do not require replacing!

+
+
+

Background

+

In their original design, IBL’s behavioral training rigs relied on a consumer-grade sound-card - the ASUS Xonar AE - for delivering auditory cues to the subject. We have identified the Xonar AE as a weak point in the design of the training rig as this choice of hardware has several severe drawbacks:

+
    +
  • Synchronization between individual components of the rig relies on TTL Signals, a standardized way of communicating between digital devices. +With the Xonar sound-card, we emulate TTL pulses on one of the soundcard’s analog audio outputs. +The resulting signal does not conform well to the TTL standard since (a) we cannot guarantee the required signal rise-times, and (b) pulse-amplitude depends on the computer’s audio volume and impedance settings. The effects are increased latencies and accidental misconfigurations. +The latter have the potential to cause synchronization issues and more problems further down the pipeline.

  • +
  • The ASUS Xonar AE does not seem to be a particularly robust piece of equipment - we’ve experienced several catastrophic failures across our rigs at IBL. Replacement hardware is increasingly hard to come by as the Asus Xonar AE is not being produced anymore.

  • +
  • The soundcard’s driver has been causing issues with specific Windows updates that require manual intervention / rollback of the respective updates.

  • +
  • There is no Windows 11 specific driver available.

  • +
+

For these reasons, we decided to replace the Xonar AE with the Bpod HiFi Module HD by Sanworks: +The HiFi Module is capable of delivering high fidelity sound stimuli at low latencies, supports proper TTL signaling as well as serial communication with the Bpod Finite State Machine and does not require any dedicated drivers. +The upgrade procedure is straightforward and should take no longer than 5-10 minutes.

+
+
+

Requirements

+

To replace your existing Xonar AE with the Bpod HiFi Module HD you will require the following:

+
    +
  • 1x Bpod HiFi Module HD

  • +
  • 1x Micro-USB to USB-A cable

  • +
  • 1x Ethernet cable (RJ45)

  • +
  • 1x RCA to 3.5 mm audio adapter

  • +
  • 1x 3 mm flathead screwdriver

  • +
+
+

Warning

+

Support for the Bpod HiFi Module was introduced with IBLRIG 8.16.0 and will not be backported to older version of IBLRIG. +Make sure to upgrade to the latest version of IBLRIG before continuing with this guide.

+
+
+
+

Upgrade Procedure

+
    +
  1. Use the 3 mm flathead screwdriver to unscrew the BNC to wire adapter from the amplifier board. +While the adapter itself is not needed anymore we will continue using the BNC cable. +Leave the other end of the BNC cable plugged into the Bpod as it is.

    +
    +_images/amp2x15_labels.png +
    +

    Disconnect the BNC to wire adapter from the amplifier board.

    +
    +
    +
  2. +
  3. Unplug the 3.5 mm audio cable from the Xonar AE sound card on the backside of the rig’s computer. +Leave the other end of the 3.5 mm audio cable connected to the amplifier board.

    +
    +_images/xonar_labels.png +
    +

    Unplug the 3.5 mm audio cable from the Xonar AE sound card.

    +
    +
    +
  4. +
  5. Connect the Bpod HiFi Module as follows:

    +
      +
    • the BNC cable connects to TTL In 2 of the Bpod (cf. step 1),

    • +
    • the 3.5 mm audio cable connects to the amplifier board via the RCA adapter (cf. step 2),

    • +
    • the USB cable connects to the rig’s computer

    • +
    • the Ethernet cable connects to one of the Bpod’s Module ports. +Warning: Bpod uses identical connectors for its Behavior ports - do not mix them up!

    • +
    +
    +_images/hifi_labels.png +
    +

    The Bpod HiFi Modules and its connections.

    +
    +
    +
  6. +
  7. Open C:/iblrigv8/settings/hardware_settings.yaml in a text-editor. +Find the section device_sound and adapt it as follows:

    +
    device_sound:
    +  OUTPUT: hifi
    +  COM_SOUND: COMx  # replace with the HiFi Module's actual COM port!
    +  AMP_TYPE: AMP2X15
    +
    +
    +
    +

    Tip

    +

    Use Windows’ device manager to identify the HiFi Module’s COM port. +The device should show up in the section labelled “Ports (COM & LPT)” after plugging it in.

    +
    +
  8. +
  9. Start IBLRIG and make sure that the hardware validation during start-up does not find any issues. +Finally, start a session and verify that you can hear the audio cues.

  10. +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..bfd37ad34 --- /dev/null +++ b/index.html @@ -0,0 +1,190 @@ + + + + + + + IBLRIG documentation — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/installation.html b/installation.html new file mode 100644 index 000000000..aeaed3815 --- /dev/null +++ b/installation.html @@ -0,0 +1,359 @@ + + + + + + + Installation guide — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Installation guide

+
+

Prerequisites

+
    +
  • A computer running Windows 10 or 11,

  • +
  • A working installation of git for windows, and

  • +
  • Notepad++ or some other decent text editor.

  • +
+
+
+

Tip

+

iblrigv8 can be installed alongside older versions of iblrig without affecting the latter.

+
+
+

Tip

+

If you believe this guide is incomplete or requires improvements, please don’t hesitate to reach out and +submit a bug report.

+
+
+

Preparing Windows PowerShell

+

Open Windows PowerShell in administrator mode:

+
    +
  • Click on the Windows Start button or press the Windows key on your keyboard.

  • +
  • Type “PowerShell” into the search bar.

  • +
  • You should see “Windows PowerShell” or “PowerShell” in the search results.

  • +
  • Right-click on it.

  • +
  • In the context menu that appears, select “Run as administrator.”

  • +
+

Now, run the following command at the prompt of Windows PowerShell:

+
Set-ExecutionPolicy RemoteSigned -Force
+
+
+
+

Tip

+

Keep the Administrator PowerShell open for the next step.

+
+
+

Background

+

In PowerShell, there are execution policies that determine the level of security for running scripts. The default execution +policy is often set to Restricted, which means that scripts are not allowed to run. However, to install Python or run +certain scripts, you need to adjust the execution policy. By setting the execution policy to RemoteSigned, you are +allowing the execution of locally created scripts without any digital signature while requiring that remotely downloaded +scripts (from the internet) must be digitally signed by a trusted source to run. This strikes a balance between security +and usability.

+
+
+
+

Installing MS Visual C++ Redistributable

+

With the Administrator PowerShell still open, run the following commands:

+
New-Item -ItemType Directory -Force -Path C:\Temp
+Invoke-WebRequest -Uri https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe  -OutFile C:\Temp\vcredist_x64.exe
+Start-Process -NoNewWindow -Wait -FilePath C:\Temp\vcredist_x64.exe -ArgumentList "/install", "/quiet", "/norestart"
+Invoke-WebRequest -Uri https://aka.ms/vs/17/release/vc_redist.x64.exe  -OutFile C:\Temp\vc_redist.x64.exe
+Start-Process -NoNewWindow -Wait -FilePath C:\Temp\vc_redist.x64.exe -ArgumentList "/install", "/quiet", "/norestart"
+
+
+
+

Warning

+

Make sure you exit the Administrator PowerShell before continuing with the next steps!

+
+
+

Background

+

These commands will create a temporary directory, download and silently install the Visual C++ Redistributable package for +64-bit Windows systems. The installer is retrieved from a Microsoft server and executed with parameters to ensure a seamless +and unobtrusive installation process.

+
+
+
+

Installing Python 3.10

+

Open a new Windows Powershell prompt (no administrator mode) and run the following:

+
New-Item -ItemType Directory -Force -Path C:\Temp
+Invoke-WebRequest -Uri https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe -OutFile C:\Temp\python-3.10.11-amd64.exe
+Start-Process -NoNewWindow -Wait -FilePath C:\Temp\python-3.10.11-amd64.exe -ArgumentList "/passive", "InstallAllUsers=0", "Include_launcher=0", "Include_test=0"
+
+
+

Check that everything worked by running the following command:

+
&$env:UserProfile\AppData\Local\Programs\Python\Python310\python.exe --version
+
+
+

The command should return Python 3.10.11

+
+

Background

+

These commands will create a temporary directory, download the Python installer from a specific URL, and then execute the +installer with specific installation options, all in a controlled and automated manner.

+
+
+
+

Installing iblrigv8

+
    +
  1. From the Powershell command line, clone the iblrigv8 branch of iblrig to C:\iblrigv8:

    +
    git clone -b iblrigv8 https://github.com/int-brain-lab/iblrig.git C:\iblrigv8
    +
    +
    +
  2. +
  3. Install a new virtual environment and update pip:

    +
    &$env:UserProfile\AppData\Local\Programs\Python\Python310\python.exe -m venv C:\iblrigv8\venv
    +C:\iblrigv8\venv\scripts\python.exe -m pip install --upgrade pip wheel
    +
    +
    +
  4. +
  5. Install iblrig in editable mode:

    +
    C:\iblrigv8\venv\scripts\Activate.ps1
    +cd C:\iblrigv8
    +pip install -e .
    +
    +
    +
  6. +
  7. Install Spinnaker SDK and PySpin:

    +
    install_spinnaker
    +install_pyspin
    +
    +
    +
  8. +
  9. Install Bonsai in portable mode:

    +
    cd C:\iblrigv8\Bonsai
    +powershell.exe .\install.ps1
    +cd ..
    +
    +
    +
  10. +
  11. Install additional tasks and extractors for personal projects (optional):

    +
    git clone https://github.com/int-brain-lab/project_extraction.git C:\project_extraction
    +cd C:\project_extraction
    +pip install -e .
    +
    +
    +
  12. +
  13. Continue with the next section.

  14. +
+
+
+

Configuration Instructions

+
+

Rig Configuration Files

+

Copy the template settings files:

+
cd C:\iblrigv8\settings
+cp hardware_settings_template.yaml hardware_settings.yaml
+cp iblrig_settings_template.yaml iblrig_settings.yaml
+explorer C:\iblrigv8\settings
+
+
+

Update the two settings files using a text-editor:

+
    +
  • iblrig_settings.yaml

  • +
  • hardware_settings.yaml

  • +
+

If the computer has been used with IBLRIG version 7 or earlier, the correct values can likely be found in C:\iblrig_params\ +.iblrig_params.json.

+
+
+

Setting up ONE

+

Setup ONE to connect to https://alyx.internationalbrainlab.org, you will need your Alyx username and password.

+

See instructions for that here: https://int-brain-lab.github.io/iblenv/notebooks_external/one_quickstart.html

+
+

Make sure you can connect to Alyx !

+

Open a Python shell in the environment and connect to Alyx (you may have to setup ONE)

+
C:\iblrigv8\venv\scripts\Activate.ps1
+ipython
+
+
+

Then at the IPython prompt

+
from one.api import ONE
+one = ONE(username='your_username', password='your_password', base_url='https://alyx.internationalbrainlab.org')
+
+
+
+
+

You can check that everything went fine by running the test suite:

+
cd C:\iblrigv8
+python -m unittest discover
+
+
+

The tests should pass to completion after around 40 seconds

+
+
+
+
+

Updating iblrigv8

+

To update iblrigv8 to the newest version:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+cd C:\iblrigv8
+git pull
+pip install --upgrade -e .
+
+
+

To update the additional tasks and extractors (see Installing iblrigv8, point 5):

+
cd C:\project_extraction
+git pull
+
+
+
+
+

Switch to specific iblrig version

+
+

Warning

+

Downgrading is not recommended and may not work as some releases break compatibility with earlier versions.

+
+

First fetch all available version tags and list them:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+cd C:\iblrigv8
+git fetch --all --tags --prune
+git tag --list '8.*'
+
+
+

Then switch to the desired version, for example 8.15.5:

+
git checkout tag/8.15.5
+pip install --upgrade -e .
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 000000000..20ccc7530 Binary files /dev/null and b/objects.inv differ diff --git a/reference.html b/reference.html new file mode 100644 index 000000000..3d3c99f34 --- /dev/null +++ b/reference.html @@ -0,0 +1,610 @@ + + + + + + + Reference — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Reference

+
+

Describing an Experiment

+
+

Experiment description file

+

All experiments are described by a file with the name +_ibl_experiment.description.yaml. This description file contains +details about the experiment such as, information about the devices used +to collect data, or the behavior tasks run during the experiment. The +content of this file is used to copy data from the acquisition computer +to the lab server and also determines the task pipeline that will be +used to extract the data on the lab servers. It’s accuracy in fully +describing the experiment is, therefore, very important!

+

Here is an example of a complete experiment description file for a +mesoscope experiment running two consecutive tasks, +biasedChoiceWorld followed by passiveChoiceWorld.

+
devices:
+  mesoscope:
+    mesoscope:
+      collection: raw_imaging_data*
+      sync_label: chrono
+  cameras:
+    belly:
+      collection: raw_video_data
+      sync_label: audio
+      width: 640
+      height: 512
+      fps: 30
+    left:
+      collection: raw_video_data
+      sync_label: audio
+    right:
+      collection: raw_video_data
+      sync_label: audio
+procedures:
+- Imaging
+projects:
+- ibl_mesoscope_active
+sync:
+  nidq:
+    acquisition_software: timeline
+    collection: raw_sync_data
+    extension: npy
+tasks:
+- _biasedChoiceWorld:
+    collection: raw_task_data_00
+    sync_label: bpod
+    extractors: [TrialRegisterRaw, ChoiceWorldTrialsTimeline, TrainingStatus]
+- passiveChoiceWorld:
+    collection: raw_task_data_01
+    sync_label: bpod
+    extractors: [PassiveRegisterRaw, PassiveTaskTimeline]
+version: 1.0.0
+
+
+
+
+

Breaking down the components of an experiment description file

+
+

Devices

+

The devices section in the experiment description file lists the set of +devices from which data was collection in the experiment. Supported +devices are Cameras, Microphone, Mesoscope, Neuropixel, Photometry and +Widefield.

+

The convention for this section is to have the device name followed by a +list of sub-devices, e.g.

+
devices:
+  cameras:
+    belly:
+      collection: raw_video_data
+      sync_label: audio
+      width: 640
+      height: 512
+      fps: 30
+    left:
+      collection: raw_video_data
+      sync_label: audio
+    right:
+      collection: raw_video_data
+      sync_label: audio
+
+
+

In the above example, cameras is the device and the sub-devices are +belly, left and right.

+

If there are no sub-devices, the sub-device is given the same name as +the device, e.g.

+
devices:
+  mesoscope:
+    mesoscope:
+      collection: raw_imaging_data*
+      sync_label: chrono
+
+
+

Each sub-device must have at least the following two keys - +collection - the folder containing the data - sync_label - the +name of the common ttl pulses in the channel map used to sync the +timestamps

+

Additional keys can also be specified for specific extractors, e.g. for +the belly camera the camera metadata passed into the camera extractor +task is defined in this file.

+
+
+

Procedures

+

The procedures section lists the set of procedures that apply to this +experiment. The list of possible procedures can be found +here.

+

As many procedure that apply to the experiment can be added e.g.

+
procedures:
+- Fiber photometry
+- Optical stimulation
+- Ephys recording with acute probe(s)
+
+
+
+
+

Projects

+

The projects section lists the set of projects that apply to this +experiment. The list of possible projects can be found +here.

+

As many projects that apply to the experiment can be added e.g.

+
projects:
+- ibl_neuropixel_brainwide_01
+- carandiniharris_midbrain_ibl
+
+
+
+
+

Sync

+

The sync section contains information about the device used to collect +the syncing data and the format of the data. Supported sync devices are +bpod, nidq, tdms, timeline. Only one sync device can be specified +per experiment description file and act as the main clock to which other +timeseries are synced.

+

An example of an experiment run with bpod as the main syncing device is,

+
sync:
+  bpod:
+    collection: raw_behavior_data
+    extension: bin
+
+
+

Another example for spikeglx electrophysiology recordings with +Neuropixel 1B probes use the nidq as main synchronisation.

+
sync:
+  nidq:
+    collection: raw_ephys_data
+    extension: bin
+    acquisition_software: spikeglx
+
+
+

Each sync device must have at least the following two keys - +collection - the folder containing the data - extension - the +file extension of the sync data

+

Optional keys include, for example acquisition_software, the +software used to acquire the sync pulses

+
+
+

Tasks

+

The tasks section contains a list of the behavioral protocols run during +the experiment. The name of the protocol must be given in the list e.g.

+
tasks:
+- _biasedChoiceWorld:
+    collection: raw_task_data_00
+    sync_label: bpod
+    extractors: [TrialRegisterRaw, ChoiceWorldTrialsTimeline, TrainingStatus]
+- passiveChoiceWorld:
+    collection: raw_task_data_01
+    sync_label: bpod
+    extractors: [PassiveRegisterRaw, PassiveTaskTimeline]
+
+
+

Each task must have at least the following two keys - collection - +the folder containing the data - sync_label - the name of the common +ttl pulses in the channel map used to sync the timestamps

+

The collection must be unique for each task. i.e. Data from two +tasks cannot be stored in the same folder.

+

If the Tasks used to extract the data are not the default tasks, the +extractors to use must be passed in as an additional key. The order of +the extractors defines their parent child relationship in the task +architecture.

+
+
+

Version

+

The version section gives version number of the experiment description +file

+
+
+
+
+

Quality check the task post-usage

+

Once a session is acquired, you can verify whether the trials data is extracted properly and that the sequence of events matches the expected logic of +the task.

+
+

Metrics definitions

+

All the metrics computed as part of the Task logic integrity QC (Task QC) are implemented in +ibllib. +When run at a behavior rig, they are computed using the Bpod data, without alignment to another DAQ’s clock.

+
+

Tip

+

The Task QC metrics definitions can be found in this documentation page. +See this page on how to write QC checks for a custom task protocol.

+
+

Some are essential, i.e. if they fail you should immediately take action and verify your rig, +and some are not as critical.

+

Essential taskQCs:

+
    +
  • check_audio_pre_trial

  • +
  • check_correct_trial_event_sequence

  • +
  • check_error_trial_event_sequence

  • +
  • check_n_trial_events

  • +
  • check_response_feedback_delays

  • +
  • check_reward_volume_set

  • +
  • check_reward_volumes

  • +
  • check_stimOn_goCue_delays

  • +
  • check_stimulus_move_before_goCue

  • +
  • check_wheel_move_before_feedback

  • +
  • check_wheel_freeze_during_quiescence

  • +
+

Non essential taskQCs:

+
    +
  • check_stimOff_itiIn_delays

  • +
  • check_positive_feedback_stimOff_delays

  • +
  • check_negative_feedback_stimOff_delays

  • +
  • check_wheel_move_during_closed_loop

  • +
  • check_response_stimFreeze_delays

  • +
  • check_detected_wheel_moves

  • +
  • check_trial_length

  • +
  • check_goCue_delays

  • +
  • check_errorCue_delays

  • +
  • check_stimOn_delays

  • +
  • check_stimOff_delays

  • +
  • check_iti_delays

  • +
  • check_stimFreeze_delays

  • +
  • check_wheel_integrity

  • +
+
+

Tip

+

The value returned by each metric is the proportion of trial that fail to pass the given test. +For example, if the value returned by check_errorCue_delays is 0.92, it means 8% of the trials failed this test.

+
+
+
+

Quantifying the task QC outcome at the session level

+

The criteria for whether a session passes the Task QC is:

+
    +
  • NOT_SET: default value (= not run yet)

  • +
  • FAIL: if at least one metric is < 95%

  • +
  • WARNING: if all metrics are >=95% , and at least one metric is <99 %

  • +
  • PASS: if all metrics are >= 99%

  • +
+

This aggregation is done on all metrics, regardless if they are essential or not.

+

The criteria is defined at +this code line

+
+
+

How to check the task QC outcome

+
+

Immediately after acquiring a session

+

At the behaviour PC, before the data have been copied, use the task_qc command with the session path:

+
task_qc C:\iblrigv8_data\Subjects\KS022\2019-12-10\001 --local
+
+
+

More information can be found here, or by running task_qc –help.

+
+
+

Once the session is registered on Alyx

+
    +
  1. Check on the Alyx webpage

    +

    From the session overview page on Alyx, +find your session click on See more session info. +The session QC is displayed in one of the right panels.

    +

    To get more information regarding which test pass or fail (contributing to this overall session QC), +you can click on the QC menu on the left. Bar-diagrams will appear, with essentials QCs on the +left, colored in green if passing.

    +
    +

    Tip

    +
    +

    You can hover over the bars with your mouse to easily know the name of the corresponding metric. +This is useful if the value of the metric is 0.

    +
    +
    +

    Warning

    +

    If an essential metric fails, run the Task QC Viewer to investigate why.

    +
    +
    +
  2. +
  3. Run the taskQC Viewer to investigate

    +
    +

    The application Task QC Viewer +enables to visualise the data streams of problematic trials.

    +
    +

    Tip

    +

    Unlike when run at the behaviour PC, after registration the QC is run on the final time-aligned data (if applicable).

    +
    +
    +

    Run the task QC metrics and viewer

    +

    Select the eid for your session to inspect, and run the following within the iblrig env:

    +
    +
    task_qc baecbddc-2b86-4eaf-a6f2-b30923225609
    +
    +
    +
    +
    +
    +
  4. +
+
+
+
+
+

Guide to develop a custom task

+
+

iblrigv8 design: inheritance

+

During the lifetime of the IBL project, we realized that multiple task variants combine with multiple hardware configurations and acquisition modalities, leading to a combinatorial explosion of possible tasks and related hardware.

+

This left us with the only option of developing a flexible task framework through hierarchical inheritance.

+
+
All tasks inherit from the iblrig.base_tasks.BaseSession class, which provides the following functionalities:
    +
  • read hardware parameters and rig parameters

  • +
  • optionally interfaces with the Alyx experimental database

  • +
  • creates the folder structure for the session

  • +
  • writes the task and rig parameters, log, and acquisition description files

  • +
+
+
+

Additionally the iblrig.base_tasks module provides “hardware mixins”. Those are classes that provide hardware-specific functionalities, such as connecting to a Bpod or a rotary encoder. They are composed with the BaseSession class to create a task.

+
+

Warning

+

This sounds complicated ? It is ! +Forecasting all possible tasks and hardware add-ons and modification is fool’s errand, however we can go through specific examples of task implementations.

+
+
+
+

Guide to Creating Your Own Task

+

What Happens When Running an IBL Task?

+
    +
  1. The task constructor is invoked, executing the following steps:

    +
      +
    • Reading of settings: hardware and IBLRIG configurations.

    • +
    • Reading of task parameters.

    • +
    • Instantiation of hardware mixins.

    • +
    +
  2. +
  3. The task initiates the run() method. Prior to execution, this +method:

    +
      +
    • Launches the hardware modules.

    • +
    • Establishes a session folder.

    • +
    • Saves the parameters to disk.

    • +
    +
  4. +
  5. The experiment unfolds: the run() method triggers the _run() +method within the child class:

    +
      +
    • Typically, this involves a loop that generates a Bpod state +machine for each trial and runs it.

    • +
    +
  6. +
  7. Upon SIGINT or when the maximum trial count is reached, the +experiment concludes. The end of the run() method includes:

    +
      +
    • Saving the final parameter file.

    • +
    • Recording administered water and session performance on Alyx.

    • +
    • Halting the mixins.

    • +
    • Initiating local server transfer.

    • +
    +
  8. +
+
+
+

Examples

+
+

Where to write your task

+

After the installation of iblrig the project extraction repository is located at the root of the C: drive. +New tasks should be added to the C:\project_extraction\iblrig_custom_tasks folder to be made visible by the iblrig GUI. +We use a convention that the task name starts with the author identifier, followed by an underscore, followed by the task name, such as olivier_awesomeChoiceWorld.

+
+
+
olivier_awesomeChoiceWorld
    +
  • __init__.py

  • +
  • task.py

  • +
  • README.md

  • +
  • task_parameters.yaml

  • +
  • test_olivier_awesomeChoiceWorld.py

  • +
+
+
+
+
+
+

Example 1: variation on biased choice world

+

We will create a a choice world task that modifies a the quiescence period duration random draw policy. +In the task.py file, the first step is to create a new task class that inherits from the BiasedChoiceWorldSession class.

+

Then we want to make sure that the task bears a distinctive protocol name, _iblrig_tasks_imagingChoiceWorld. +We also create the command line entry point for the task that will be used by the iblrig GUI.

+

Also, in this case we can leverage the IBL infrastructure to perform extraction of the trials using existing extractors extractor_tasks = [‘TrialRegisterRaw’, ‘ChoiceWorldTrials’]

+
+
import iblrig.misc
+from iblrig.base_choice_world import BiasedChoiceWorldSession
+
+
+class Session(BiasedChoiceWorldSession):
+    protocol_name = "_iblrig_tasks_imagingChoiceWorld"
+
+    def __init__(self, *args, **kwargs):
+        self.extractor_tasks = ['TrialRegisterRaw', 'ChoiceWorldTrials']
+        super().__init__(*args, **kwargs)
+
+if __name__ == "__main__":  # pragma: no cover
+    kwargs = iblrig.misc.get_task_arguments(parents=[Session.extra_parser()])
+    sess = Session(**kwargs)
+    sess.run()
+
+
+
+

In this case the parent class BiasedChoiceWorldSession has a method that draws the quiescence period. We are going to overload this method to add our own policy. This means the parent method will be fully replaced by our implementation. +The class now looks like this:

+
+
class Session(BiasedChoiceWorldSession):
+    protocol_name = "_iblrig_tasks_imagingChoiceWorld"
+
+    def draw_quiescent_period(self):
+        """
+        For this task we double the quiescence period texp draw and remove the absolute
+        offset of 200ms. The resulting is a truncated exp distribution between 400ms and 1 sec
+        """
+        return iblrig.misc.texp(factor=0.35 * 2, min_=0.2 * 2, max_=0.5 * 2)
+
+
+
+

Et voilà, in a few lines, we re-used the whole biased choice world implementation to add a custom parameter. This is the most trivial and easy example. +The full code is available here.

+
+
+

Example 2: re-writing a state-machine for a biased choice world task

+

In some instances changes in the task logic require to go deeper and re-write the sequence of task events. In bpod parlance, we are talking about rewritng the state-machine code.

+

Coming, for now here is an example of such a task.

+

#.. include:: reference_developer_guide.rst

+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/reference_description_file.html b/reference_description_file.html new file mode 100644 index 000000000..8c3c1164e --- /dev/null +++ b/reference_description_file.html @@ -0,0 +1,315 @@ + + + + + + + Describing an Experiment — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Describing an Experiment

+
+

Experiment description file

+

All experiments are described by a file with the name +_ibl_experiment.description.yaml. This description file contains +details about the experiment such as, information about the devices used +to collect data, or the behavior tasks run during the experiment. The +content of this file is used to copy data from the acquisition computer +to the lab server and also determines the task pipeline that will be +used to extract the data on the lab servers. It’s accuracy in fully +describing the experiment is, therefore, very important!

+

Here is an example of a complete experiment description file for a +mesoscope experiment running two consecutive tasks, +biasedChoiceWorld followed by passiveChoiceWorld.

+
devices:
+  mesoscope:
+    mesoscope:
+      collection: raw_imaging_data*
+      sync_label: chrono
+  cameras:
+    belly:
+      collection: raw_video_data
+      sync_label: audio
+      width: 640
+      height: 512
+      fps: 30
+    left:
+      collection: raw_video_data
+      sync_label: audio
+    right:
+      collection: raw_video_data
+      sync_label: audio
+procedures:
+- Imaging
+projects:
+- ibl_mesoscope_active
+sync:
+  nidq:
+    acquisition_software: timeline
+    collection: raw_sync_data
+    extension: npy
+tasks:
+- _biasedChoiceWorld:
+    collection: raw_task_data_00
+    sync_label: bpod
+    extractors: [TrialRegisterRaw, ChoiceWorldTrialsTimeline, TrainingStatus]
+- passiveChoiceWorld:
+    collection: raw_task_data_01
+    sync_label: bpod
+    extractors: [PassiveRegisterRaw, PassiveTaskTimeline]
+version: 1.0.0
+
+
+
+
+

Breaking down the components of an experiment description file

+
+

Devices

+

The devices section in the experiment description file lists the set of +devices from which data was collection in the experiment. Supported +devices are Cameras, Microphone, Mesoscope, Neuropixel, Photometry and +Widefield.

+

The convention for this section is to have the device name followed by a +list of sub-devices, e.g.

+
devices:
+  cameras:
+    belly:
+      collection: raw_video_data
+      sync_label: audio
+      width: 640
+      height: 512
+      fps: 30
+    left:
+      collection: raw_video_data
+      sync_label: audio
+    right:
+      collection: raw_video_data
+      sync_label: audio
+
+
+

In the above example, cameras is the device and the sub-devices are +belly, left and right.

+

If there are no sub-devices, the sub-device is given the same name as +the device, e.g.

+
devices:
+  mesoscope:
+    mesoscope:
+      collection: raw_imaging_data*
+      sync_label: chrono
+
+
+

Each sub-device must have at least the following two keys - +collection - the folder containing the data - sync_label - the +name of the common ttl pulses in the channel map used to sync the +timestamps

+

Additional keys can also be specified for specific extractors, e.g. for +the belly camera the camera metadata passed into the camera extractor +task is defined in this file.

+
+
+

Procedures

+

The procedures section lists the set of procedures that apply to this +experiment. The list of possible procedures can be found +here.

+

As many procedure that apply to the experiment can be added e.g.

+
procedures:
+- Fiber photometry
+- Optical stimulation
+- Ephys recording with acute probe(s)
+
+
+
+
+

Projects

+

The projects section lists the set of projects that apply to this +experiment. The list of possible projects can be found +here.

+

As many projects that apply to the experiment can be added e.g.

+
projects:
+- ibl_neuropixel_brainwide_01
+- carandiniharris_midbrain_ibl
+
+
+
+
+

Sync

+

The sync section contains information about the device used to collect +the syncing data and the format of the data. Supported sync devices are +bpod, nidq, tdms, timeline. Only one sync device can be specified +per experiment description file and act as the main clock to which other +timeseries are synced.

+

An example of an experiment run with bpod as the main syncing device is,

+
sync:
+  bpod:
+    collection: raw_behavior_data
+    extension: bin
+
+
+

Another example for spikeglx electrophysiology recordings with +Neuropixel 1B probes use the nidq as main synchronisation.

+
sync:
+  nidq:
+    collection: raw_ephys_data
+    extension: bin
+    acquisition_software: spikeglx
+
+
+

Each sync device must have at least the following two keys - +collection - the folder containing the data - extension - the +file extension of the sync data

+

Optional keys include, for example acquisition_software, the +software used to acquire the sync pulses

+
+
+

Tasks

+

The tasks section contains a list of the behavioral protocols run during +the experiment. The name of the protocol must be given in the list e.g.

+
tasks:
+- _biasedChoiceWorld:
+    collection: raw_task_data_00
+    sync_label: bpod
+    extractors: [TrialRegisterRaw, ChoiceWorldTrialsTimeline, TrainingStatus]
+- passiveChoiceWorld:
+    collection: raw_task_data_01
+    sync_label: bpod
+    extractors: [PassiveRegisterRaw, PassiveTaskTimeline]
+
+
+

Each task must have at least the following two keys - collection - +the folder containing the data - sync_label - the name of the common +ttl pulses in the channel map used to sync the timestamps

+

The collection must be unique for each task. i.e. Data from two +tasks cannot be stored in the same folder.

+

If the Tasks used to extract the data are not the default tasks, the +extractors to use must be passed in as an additional key. The order of +the extractors defines their parent child relationship in the task +architecture.

+
+
+

Version

+

The version section gives version number of the experiment description +file

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/reference_developer_guide.html b/reference_developer_guide.html new file mode 100644 index 000000000..8e25b5e22 --- /dev/null +++ b/reference_developer_guide.html @@ -0,0 +1,256 @@ + + + + + + + Developer Guide — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Developer Guide

+
+

Versioning Scheme

+

IBLRIG v8 uses Semantic Versioning 2.0.0. +Its version string (currently “8.20.0”) is a combination of three fields, separated by dots:

+

+MAJOR . MINOR . PATCH

    +
  • The MAJOR field is only incremented for breaking changes, i.e., changes that are not backward compatible with previous changes. +Releases of IBLRIG v8, for instance, are generally incompatible with IBLRIG v7.

  • +
  • The MINOR field will be incremented upon adding new, backwards compatible features.

  • +
  • The PATCH field will be incremented with each new, backwards compatible bugfix release that does not implement a new feature.

  • +
+

On the developer side, these 3 fields are manually controlled by, both

+
+
    +
  1. adjusting the variable __version__ in iblrig/__init__.py, and

  2. +
  3. adding the corresponding version string to a commit as a git tag, +for instance:

    +
    git tag 8.8.4
    +git push origin --tags
    +
    +
    +
  4. +
+
+

The version string displayed by IBLRIG may include additional fields, such as in “8.20.0.post3+dirty”. +Here,

+
    +
  • post3 indicates the third unversioned commit after the latest versioned release, and

  • +
  • dirty indicates the presence of uncommited changes in your local repository of IBLRIG.

  • +
+

Both of these fields are inferred by means of git describe and do not require manual interaction from the developer.

+
+
+

Installing Developer Dependencies

+

To install additional dependencies needed for working on IBLRIG’s code-base, run the following within the venv:

+
pip install -U -e .[DEV]
+
+
+
+
+

Running Unit Tests Locally

+

To run unit tests locally, run the following within IBLRIG’s venv:

+
pytest
+
+
+

This will also generate a coverage report which can be found in the htmlcov directory.

+
+
+

Linting & Formatting

+

To lint your code, run the following within IBLRIG’s venv:

+
ruff check .
+
+
+

Adding the commandline flag --fix will automatically fix issues that are deemed safe to handle:

+
ruff check . --fix
+
+
+

To check if your code conforms to the Black code style, run:

+
ruff format . --check
+
+
+

To reformat your code according to the Black code style, run:

+
ruff format .
+
+
+

Refer to Ruff Formater’s documentation for further details.

+
+
+

Release Checklist

+
    +
  1. update CHANGELOG.md including changes from the last tag

  2. +
  3. Pull request to iblrigv8dev

  4. +
  5. Check CI and eventually wet lab test

  6. +
  7. Pull request to iblrigv8

  8. +
  9. Merge PR

  10. +
  11. git tag the release in accordance to the version number below (after merge!)

  12. +
+
+
+

Building the documentation

+
# make sure pre-requisites are installed
+pip install --upgrade -e .[DEV]
+# create the static directory
+rm -rf ./docs/build
+mkdir -p ./docs/build/html/_static
+# unit tests generate task diagrams
+python -m unittest discover ./iblrig/test
+# generate class diagrams
+pyreverse -o png -m y --ignore iblrig.test -A --output-directory ./docs/build/html/_static ./iblrig_tasks
+# build and serve the docs locally
+sphinx-autobuild ./docs/source ./docs/build/html/
+
+
+
+

Contribute to the documentation

+

To write the documentation:

+
    +
  • Write the documentation in the iblrig/docs/source folder

  • +
  • If you are writing in a new file, add it to the index.rst so it appears in the table of content

  • +
  • Push all your changes to the iblrigv8dev branch ; if this branch does not exist, create it first

  • +
+

To release the documentation onto the website:

+
    +
  • Wait for the next release, or

  • +
  • Manually trigger the GitHub action by clicking “Run Workflow” (select master) here

  • +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/reference_task_qc.html b/reference_task_qc.html new file mode 100644 index 000000000..9db21b85e --- /dev/null +++ b/reference_task_qc.html @@ -0,0 +1,250 @@ + + + + + + + Quality check the task post-usage — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Quality check the task post-usage

+

Once a session is acquired, you can verify whether the trials data is extracted properly and that the sequence of events matches the expected logic of +the task.

+
+

Metrics definitions

+

All the metrics computed as part of the Task logic integrity QC (Task QC) are implemented in +ibllib. +When run at a behavior rig, they are computed using the Bpod data, without alignment to another DAQ’s clock.

+
+

Tip

+

The Task QC metrics definitions can be found in this documentation page. +See this page on how to write QC checks for a custom task protocol.

+
+

Some are essential, i.e. if they fail you should immediately take action and verify your rig, +and some are not as critical.

+

Essential taskQCs:

+
    +
  • check_audio_pre_trial

  • +
  • check_correct_trial_event_sequence

  • +
  • check_error_trial_event_sequence

  • +
  • check_n_trial_events

  • +
  • check_response_feedback_delays

  • +
  • check_reward_volume_set

  • +
  • check_reward_volumes

  • +
  • check_stimOn_goCue_delays

  • +
  • check_stimulus_move_before_goCue

  • +
  • check_wheel_move_before_feedback

  • +
  • check_wheel_freeze_during_quiescence

  • +
+

Non essential taskQCs:

+
    +
  • check_stimOff_itiIn_delays

  • +
  • check_positive_feedback_stimOff_delays

  • +
  • check_negative_feedback_stimOff_delays

  • +
  • check_wheel_move_during_closed_loop

  • +
  • check_response_stimFreeze_delays

  • +
  • check_detected_wheel_moves

  • +
  • check_trial_length

  • +
  • check_goCue_delays

  • +
  • check_errorCue_delays

  • +
  • check_stimOn_delays

  • +
  • check_stimOff_delays

  • +
  • check_iti_delays

  • +
  • check_stimFreeze_delays

  • +
  • check_wheel_integrity

  • +
+
+

Tip

+

The value returned by each metric is the proportion of trial that fail to pass the given test. +For example, if the value returned by check_errorCue_delays is 0.92, it means 8% of the trials failed this test.

+
+
+
+

Quantifying the task QC outcome at the session level

+

The criteria for whether a session passes the Task QC is:

+
    +
  • NOT_SET: default value (= not run yet)

  • +
  • FAIL: if at least one metric is < 95%

  • +
  • WARNING: if all metrics are >=95% , and at least one metric is <99 %

  • +
  • PASS: if all metrics are >= 99%

  • +
+

This aggregation is done on all metrics, regardless if they are essential or not.

+

The criteria is defined at +this code line

+
+
+

How to check the task QC outcome

+
+

Immediately after acquiring a session

+

At the behaviour PC, before the data have been copied, use the task_qc command with the session path:

+
task_qc C:\iblrigv8_data\Subjects\KS022\2019-12-10\001 --local
+
+
+

More information can be found here, or by running task_qc –help.

+
+
+

Once the session is registered on Alyx

+
    +
  1. Check on the Alyx webpage

    +

    From the session overview page on Alyx, +find your session click on See more session info. +The session QC is displayed in one of the right panels.

    +

    To get more information regarding which test pass or fail (contributing to this overall session QC), +you can click on the QC menu on the left. Bar-diagrams will appear, with essentials QCs on the +left, colored in green if passing.

    +
    +

    Tip

    +
    +

    You can hover over the bars with your mouse to easily know the name of the corresponding metric. +This is useful if the value of the metric is 0.

    +
    +
    +

    Warning

    +

    If an essential metric fails, run the Task QC Viewer to investigate why.

    +
    +
    +
  2. +
  3. Run the taskQC Viewer to investigate

    +
    +

    The application Task QC Viewer +enables to visualise the data streams of problematic trials.

    +
    +

    Tip

    +

    Unlike when run at the behaviour PC, after registration the QC is run on the final time-aligned data (if applicable).

    +
    +
    +

    Run the task QC metrics and viewer

    +

    Select the eid for your session to inspect, and run the following within the iblrig env:

    +
    +
    task_qc baecbddc-2b86-4eaf-a6f2-b30923225609
    +
    +
    +
    +
    +
    +
  4. +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/reference_write_your_own_task.html b/reference_write_your_own_task.html new file mode 100644 index 000000000..bb0d16dc3 --- /dev/null +++ b/reference_write_your_own_task.html @@ -0,0 +1,259 @@ + + + + + + + Guide to develop a custom task — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Guide to develop a custom task

+
+

iblrigv8 design: inheritance

+

During the lifetime of the IBL project, we realized that multiple task variants combine with multiple hardware configurations and acquisition modalities, leading to a combinatorial explosion of possible tasks and related hardware.

+

This left us with the only option of developing a flexible task framework through hierarchical inheritance.

+
+
All tasks inherit from the iblrig.base_tasks.BaseSession class, which provides the following functionalities:
    +
  • read hardware parameters and rig parameters

  • +
  • optionally interfaces with the Alyx experimental database

  • +
  • creates the folder structure for the session

  • +
  • writes the task and rig parameters, log, and acquisition description files

  • +
+
+
+

Additionally the iblrig.base_tasks module provides “hardware mixins”. Those are classes that provide hardware-specific functionalities, such as connecting to a Bpod or a rotary encoder. They are composed with the BaseSession class to create a task.

+
+

Warning

+

This sounds complicated ? It is ! +Forecasting all possible tasks and hardware add-ons and modification is fool’s errand, however we can go through specific examples of task implementations.

+
+
+
+

Guide to Creating Your Own Task

+

What Happens When Running an IBL Task?

+
    +
  1. The task constructor is invoked, executing the following steps:

    +
      +
    • Reading of settings: hardware and IBLRIG configurations.

    • +
    • Reading of task parameters.

    • +
    • Instantiation of hardware mixins.

    • +
    +
  2. +
  3. The task initiates the run() method. Prior to execution, this +method:

    +
      +
    • Launches the hardware modules.

    • +
    • Establishes a session folder.

    • +
    • Saves the parameters to disk.

    • +
    +
  4. +
  5. The experiment unfolds: the run() method triggers the _run() +method within the child class:

    +
      +
    • Typically, this involves a loop that generates a Bpod state +machine for each trial and runs it.

    • +
    +
  6. +
  7. Upon SIGINT or when the maximum trial count is reached, the +experiment concludes. The end of the run() method includes:

    +
      +
    • Saving the final parameter file.

    • +
    • Recording administered water and session performance on Alyx.

    • +
    • Halting the mixins.

    • +
    • Initiating local server transfer.

    • +
    +
  8. +
+
+
+

Examples

+
+

Where to write your task

+

After the installation of iblrig the project extraction repository is located at the root of the C: drive. +New tasks should be added to the C:\project_extraction\iblrig_custom_tasks folder to be made visible by the iblrig GUI. +We use a convention that the task name starts with the author identifier, followed by an underscore, followed by the task name, such as olivier_awesomeChoiceWorld.

+
+
+
olivier_awesomeChoiceWorld
    +
  • __init__.py

  • +
  • task.py

  • +
  • README.md

  • +
  • task_parameters.yaml

  • +
  • test_olivier_awesomeChoiceWorld.py

  • +
+
+
+
+
+
+

Example 1: variation on biased choice world

+

We will create a a choice world task that modifies a the quiescence period duration random draw policy. +In the task.py file, the first step is to create a new task class that inherits from the BiasedChoiceWorldSession class.

+

Then we want to make sure that the task bears a distinctive protocol name, _iblrig_tasks_imagingChoiceWorld. +We also create the command line entry point for the task that will be used by the iblrig GUI.

+

Also, in this case we can leverage the IBL infrastructure to perform extraction of the trials using existing extractors extractor_tasks = [‘TrialRegisterRaw’, ‘ChoiceWorldTrials’]

+
+
import iblrig.misc
+from iblrig.base_choice_world import BiasedChoiceWorldSession
+
+
+class Session(BiasedChoiceWorldSession):
+    protocol_name = "_iblrig_tasks_imagingChoiceWorld"
+
+    def __init__(self, *args, **kwargs):
+        self.extractor_tasks = ['TrialRegisterRaw', 'ChoiceWorldTrials']
+        super().__init__(*args, **kwargs)
+
+if __name__ == "__main__":  # pragma: no cover
+    kwargs = iblrig.misc.get_task_arguments(parents=[Session.extra_parser()])
+    sess = Session(**kwargs)
+    sess.run()
+
+
+
+

In this case the parent class BiasedChoiceWorldSession has a method that draws the quiescence period. We are going to overload this method to add our own policy. This means the parent method will be fully replaced by our implementation. +The class now looks like this:

+
+
class Session(BiasedChoiceWorldSession):
+    protocol_name = "_iblrig_tasks_imagingChoiceWorld"
+
+    def draw_quiescent_period(self):
+        """
+        For this task we double the quiescence period texp draw and remove the absolute
+        offset of 200ms. The resulting is a truncated exp distribution between 400ms and 1 sec
+        """
+        return iblrig.misc.texp(factor=0.35 * 2, min_=0.2 * 2, max_=0.5 * 2)
+
+
+
+

Et voilà, in a few lines, we re-used the whole biased choice world implementation to add a custom parameter. This is the most trivial and easy example. +The full code is available here.

+
+
+

Example 2: re-writing a state-machine for a biased choice world task

+

In some instances changes in the task logic require to go deeper and re-write the sequence of task events. In bpod parlance, we are talking about rewritng the state-machine code.

+

Coming, for now here is an example of such a task.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 000000000..dc849ef03 --- /dev/null +++ b/search.html @@ -0,0 +1,149 @@ + + + + + + Search — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 000000000..479864bc8 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"8.10.0": [[0, "id51"]], "8.10.1": [[0, "id50"]], "8.10.2": [[0, "id49"]], "8.11.0": [[0, "id48"]], "8.11.1": [[0, "id47"]], "8.11.2": [[0, "id46"]], "8.11.3": [[0, "id45"]], "8.11.4": [[0, "id44"]], "8.11.5": [[0, "id43"]], "8.12.0": [[0, "id42"]], "8.12.1": [[0, "id41"]], "8.12.10": [[0, "id32"]], "8.12.11": [[0, "id31"]], "8.12.12": [[0, "id30"]], "8.12.13": [[0, "id29"]], "8.12.2": [[0, "id40"]], "8.12.3": [[0, "id39"]], "8.12.4": [[0, "id38"]], "8.12.5": [[0, "id37"]], "8.12.6": [[0, "id36"]], "8.12.7": [[0, "id35"]], "8.12.8": [[0, "id34"]], "8.12.9": [[0, "id33"]], "8.13.0": [[0, "id28"]], "8.13.1": [[0, "id27"]], "8.13.2": [[0, "id26"]], "8.13.3": [[0, "id25"]], "8.13.4": [[0, "id24"]], "8.13.5": [[0, "id23"]], "8.14.0": [[0, "id22"]], "8.14.1": [[0, "id21"]], "8.14.2": [[0, "id20"]], "8.15.0": [[0, "id19"]], "8.15.1": [[0, "id18"]], "8.15.2": [[0, "id17"]], "8.15.3": [[0, "id16"]], "8.15.4": [[0, "id15"]], "8.15.5": [[0, "id14"]], "8.15.6": [[0, "id13"]], "8.16.0": [[0, "id12"]], "8.16.1": [[0, "id11"]], "8.17.0": [[0, "id10"]], "8.18.0": [[0, "id9"]], "8.19.0": [[0, "id8"]], "8.19.1": [[0, "id7"]], "8.19.2": [[0, "id6"]], "8.19.3": [[0, "id5"]], "8.19.4": [[0, "id4"]], "8.19.5": [[0, "id3"]], "8.19.6": [[0, "id2"]], "8.20.0": [[0, "id1"]], "8.9.0": [[0, "id56"]], "8.9.1": [[0, "id55"]], "8.9.2": [[0, "id54"]], "8.9.3": [[0, "id53"]], "8.9.4": [[0, "id52"]], "Background": [[2, "background"], [4, null], [4, null], [4, null]], "Behind the Copy Scripts": [[10, "behind-the-copy-scripts"], [12, "behind-the-copy-scripts"]], "Breaking down the components of an experiment description file": [[5, "breaking-down-the-components-of-an-experiment-description-file"], [6, "breaking-down-the-components-of-an-experiment-description-file"]], "Bug Reports & Feature Requests": [[1, "bug-reports-feature-requests"]], "Building the documentation": [[7, "building-the-documentation"]], "Camera Issues": [[1, "camera-issues"]], "Chaining several tasks together": [[10, "chaining-several-tasks-together"], [11, "chaining-several-tasks-together"]], "Changelog": [[0, "changelog"]], "Clean-up local data": [[10, "clean-up-local-data"], [12, "clean-up-local-data"]], "Configuration Instructions": [[4, "configuration-instructions"]], "Contents:": [[3, null]], "Contribute to the documentation": [[7, "contribute-to-the-documentation"]], "Copy command": [[10, "copy-command"], [10, "id5"], [13, "copy-command"], [14, "copy-command"]], "Copy commands": [[10, "copy-commands"], [12, "copy-commands"]], "Defining Default Position & Size of Bonsai Visualizers": [[1, "defining-default-position-size-of-bonsai-visualizers"]], "Describing an Experiment": [[5, "describing-an-experiment"], [6, "describing-an-experiment"]], "Developer Guide": [[7, "developer-guide"]], "Devices": [[5, "devices"], [6, "devices"]], "Example 1: variation on biased choice world": [[5, "example-1-variation-on-biased-choice-world"], [9, "example-1-variation-on-biased-choice-world"]], "Example 2: re-writing a state-machine for a biased choice world task": [[5, "example-2-re-writing-a-state-machine-for-a-biased-choice-world-task"], [9, "example-2-re-writing-a-state-machine-for-a-biased-choice-world-task"]], "Example of workflow": [[10, "example-of-workflow"], [12, "example-of-workflow"]], "Examples": [[5, "examples"], [9, "examples"]], "Experiment description file": [[5, "experiment-description-file"], [6, "experiment-description-file"]], "First Aid": [[1, "first-aid"]], "Flushing the valve": [[10, "flushing-the-valve"], [11, "flushing-the-valve"]], "Frame2TTL": [[1, "frame2ttl"]], "Frequently Asked Questions": [[1, "frequently-asked-questions"]], "General": [[1, "general"]], "Guide to Creating Your Own Task": [[5, "guide-to-creating-your-own-task"], [9, "guide-to-creating-your-own-task"]], "Guide to develop a custom task": [[5, "guide-to-develop-a-custom-task"], [9, "guide-to-develop-a-custom-task"]], "Hardware Guide": [[2, "hardware-guide"]], "How to check the task QC outcome": [[5, "how-to-check-the-task-qc-outcome"], [8, "how-to-check-the-task-qc-outcome"]], "IBLRIG documentation": [[3, "iblrig-documentation"]], "Immediately after acquiring a session": [[5, "immediately-after-acquiring-a-session"], [8, "immediately-after-acquiring-a-session"]], "Installation guide": [[4, "installation-guide"]], "Installing Developer Dependencies": [[7, "installing-developer-dependencies"]], "Installing MS Visual C++ Redistributable": [[4, "installing-ms-visual-c-redistributable"]], "Installing Python 3.10": [[4, "installing-python-3-10"]], "Installing drivers": [[10, "installing-drivers"], [14, "installing-drivers"]], "Installing iblrigv8": [[4, "installing-iblrigv8"]], "Interfacing with Alyx": [[10, "interfacing-with-alyx"], [11, "interfacing-with-alyx"]], "Linting & Formatting": [[7, "linting-formatting"]], "Look at the raw data": [[10, "look-at-the-raw-data"], [13, "look-at-the-raw-data"]], "Make sure you can connect to Alyx !": [[4, "exercise-0"]], "Metrics definitions": [[5, "metrics-definitions"], [8, "metrics-definitions"]], "Neuropixel recording with iblrigv8": [[10, "neuropixel-recording-with-iblrigv8"], [13, "neuropixel-recording-with-iblrigv8"]], "Once the session is registered on Alyx": [[5, "once-the-session-is-registered-on-alyx"], [8, "once-the-session-is-registered-on-alyx"]], "Preparing Windows PowerShell": [[4, "preparing-windows-powershell"]], "Prerequisites": [[4, "prerequisites-0"]], "Procedures": [[5, "procedures"], [6, "procedures"]], "Projects": [[5, "projects"], [6, "projects"]], "Quality check the task post-usage": [[5, "quality-check-the-task-post-usage"], [8, "quality-check-the-task-post-usage"]], "Quantifying the task QC outcome at the session level": [[5, "quantifying-the-task-qc-outcome-at-the-session-level"], [8, "quantifying-the-task-qc-outcome-at-the-session-level"]], "Reference": [[5, "reference"]], "Release Checklist": [[7, "release-checklist"]], "Requirements": [[2, "requirements"]], "Rig Configuration Files": [[4, "rig-configuration-files"]], "Run the task QC metrics and viewer": [[5, "exercise-0"], [8, "exercise-0"]], "Running Unit Tests Locally": [[7, "running-unit-tests-locally"]], "Running a behaviour experiment": [[10, "running-a-behaviour-experiment"], [11, "running-a-behaviour-experiment"]], "Running a single task": [[10, "running-a-single-task"], [11, "running-a-single-task"]], "Screen Issues": [[1, "screen-issues"]], "Setting up ONE": [[4, "setting-up-one"]], "Settings config": [[10, "settings-config"], [14, "settings-config"]], "Setup": [[10, "setup"], [10, "id3"], [13, "setup"], [14, "setup"]], "Sound Issues": [[1, "sound-issues"]], "Starting a Task": [[10, "starting-a-task"], [11, "starting-a-task"]], "Starting a task": [[10, "id1"], [10, "id4"], [13, "starting-a-task"], [14, "starting-a-task"]], "Supplementary Controls": [[10, "supplementary-controls"], [11, "supplementary-controls"]], "Switch to specific iblrig version": [[4, "switch-to-specific-iblrig-version"]], "Sync": [[5, "sync"], [6, "sync"]], "Tasks": [[5, "tasks"], [6, "tasks"]], "The Command Line Interface": [[10, "the-command-line-interface"], [11, "the-command-line-interface"]], "The Graphical User Interface": [[10, "the-graphical-user-interface"], [11, "the-graphical-user-interface"]], "Updating iblrigv8": [[4, "updating-iblrigv8"]], "Upgrade Procedure": [[2, "upgrade-procedure"]], "Upgrading Xonar AE to Bpod HiFi Module": [[2, "upgrading-xonar-ae-to-bpod-hifi-module"]], "Usage": [[10, "usage"], [10, "id2"], [10, "id6"], [12, "usage"], [13, "usage"], [14, "usage"]], "Using IBLRIG v8": [[10, "using-iblrig-v8"]], "Version": [[5, "version"], [6, "version"]], "Versioning Scheme": [[7, "versioning-scheme"]], "Video acquisition computer": [[10, "video-acquisition-computer"], [14, "video-acquisition-computer"]], "Where to write your task": [[5, null], [9, null]], "Workflow": [[10, "workflow"], [12, "workflow"]], "You can check that everything went fine by running the test suite:": [[4, "exercise-1"]], "iblrigv8 design: inheritance": [[5, "iblrigv8-design-inheritance"], [9, "iblrigv8-design-inheritance"]]}, "docnames": ["changelog", "faq", "hardware", "index", "installation", "reference", "reference_description_file", "reference_developer_guide", "reference_task_qc", "reference_write_your_own_task", "usage", "usage_behavior", "usage_copy", "usage_neuropixel", "usage_video"], "envversion": {"sphinx": 61, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["changelog.rst", "faq.rst", "hardware.rst", "index.rst", "installation.rst", "reference.rst", "reference_description_file.rst", "reference_developer_guide.rst", "reference_task_qc.rst", "reference_write_your_own_task.rst", "usage.rst", "usage_behavior.rst", "usage_copy.rst", "usage_neuropixel.rst", "usage_video.rst"], "indexentries": {}, "objects": {}, "objnames": {}, "objtypes": {}, "terms": {"": [0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12], "0": [2, 4, 5, 6, 7, 8, 9], "001": [5, 8, 10, 12], "002": [10, 12], "003": [10, 12], "01": [10, 12], "01_1_subject": [10, 12], "1": [1, 2, 4, 6, 10, 11, 12, 14], "10": [2, 3, 5, 8], "1024": [10, 14], "11": [2, 4], "12": [5, 8], "1280": [10, 14], "12v": 1, "15": 4, "16": 2, "16b06f60": 4, "17": 4, "1a": 1, "1b": [5, 6], "1x": 2, "2": [1, 2, 7, 10, 12, 13], "20": 7, "200m": [5, 9], "2019": [5, 8], "2020": [10, 12], "2b86": [5, 8], "3": [1, 2, 3, 7], "30": [5, 6, 10, 14], "35": [5, 9], "3b20": 4, "4": 7, "40": 4, "400m": [5, 9], "42": 0, "4eaf": [5, 8], "4ff2": 4, "5": [1, 2, 4, 5, 9], "504": 0, "512": [5, 6], "5e9b7962f9a": 4, "6": 4, "64": 4, "640": [5, 6], "7": [4, 10, 12], "8": [2, 4, 5, 7, 8], "92": [5, 8], "95": [5, 8], "99": [5, 8], "A": [2, 4, 7, 10, 11, 12], "As": [5, 6], "At": [5, 8, 10, 12], "By": [4, 10, 12], "For": [2, 5, 8, 9, 10, 11, 12], "If": [1, 4, 5, 6, 7, 8, 10, 11], "In": [2, 4, 5, 6, 9], "It": [1, 5, 6, 9], "Its": 7, "On": 7, "The": [0, 1, 2, 4, 5, 6, 7, 8, 9, 12, 13, 14], "Then": [4, 5, 9], "There": 2, "These": [4, 10, 11], "To": [1, 2, 4, 5, 7, 8, 10, 11, 12, 13, 14], "With": [2, 4, 10, 12], "__init__": [5, 7, 9], "__main__": [5, 9], "__name__": [5, 9], "__version__": 7, "_biasedchoiceworld": [5, 6], "_define_messag": 0, "_devic": [10, 12], "_ibl_experi": [5, 6, 10, 12], "_iblrig_tasks_ephyschoiceworld": [10, 11], "_iblrig_tasks_imagingchoiceworld": [5, 9], "_iblrig_tasks_passivechoiceworld": [10, 11], "_iblrig_tasks_trainingchoiceworld": [10, 11], "_iterate_protocol": 0, "_run": [5, 9], "_static": 7, "a6f2": [5, 8], "abil": 0, "abl": 1, "about": [0, 1, 5, 6, 9], "abov": [1, 5, 6, 10, 12], "absolut": [5, 9], "accept": 0, "access": [0, 10, 11, 13], "accident": 2, "accord": [7, 10, 13], "account": [10, 11], "accuraci": [5, 6], "achiev": [10, 11], "acquir": 6, "acquisit": [0, 3, 5, 6, 9, 12], "acquisition_softwar": [5, 6], "across": [0, 2], "act": [1, 5, 6], "action": [5, 7, 8, 10, 11], "activ": [1, 4, 10, 11, 12, 13, 14], "actual": [1, 2, 10, 12, 14], "acut": [5, 6], "ad": [0, 5, 6, 7, 9, 10, 14], "adapt": [0, 1, 2], "add": [0, 5, 7, 9, 10, 11], "addit": [0, 1, 4, 5, 6, 7], "addition": [1, 5, 9, 10, 12], "address": 0, "adjust": [1, 4, 7], "administ": [5, 9], "administr": [0, 4], "advancedchoiceworld": 0, "advertis": 0, "ae": 3, "affect": 4, "after": [0, 1, 2, 4, 7, 9, 10, 11], "again": [1, 10, 11], "aggreg": [5, 8], "ago": [10, 12], "aid": 3, "aka": 4, "algernon": [10, 11], "align": [1, 5, 8, 10, 14], "aliv": [10, 11], "all": [0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12], "allow": [0, 4, 10, 11, 12], "alongsid": 4, "alreadi": [10, 12], "also": [0, 1, 5, 6, 7, 9], "although": [10, 11], "alyx": [0, 9], "ambient": 0, "amd64": 4, "amp2x15": [0, 2], "amp_typ": [0, 2], "amplifi": [0, 2], "amplitud": 2, "an": [1, 3, 8, 9, 10, 11, 12, 14], "analog": [1, 2], "ani": [1, 2, 4, 10, 11], "anoth": [5, 6, 8, 10, 12], "anymor": 2, "api": 4, "appdata": 4, "appear": [1, 4, 5, 7, 8], "append": [0, 10, 11], "appendix": 1, "appli": [5, 6], "applic": [5, 8], "approach": [10, 11], "ar": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "arbitrari": 0, "architectur": [5, 6], "arg": [0, 5, 9], "argument": [0, 10, 12], "argumentlist": 4, "around": 4, "ask": 3, "assign": [10, 14], "assist": 1, "asu": 2, "attach": 1, "attribut": 0, "audio": [2, 5, 6], "auditori": 2, "author": [5, 9], "autobuild": 7, "autom": [0, 1, 4], "automat": [0, 7, 10, 11, 12], "avail": [0, 2, 4, 5, 9, 10, 11], "avoid": [0, 1, 10, 12], "b": [2, 4], "b30923225609": [5, 8], "b699": 4, "back": [0, 1], "backport": 2, "backsid": 2, "backup": 1, "backward": 7, "baecbddc": [5, 8], "balanc": 4, "bar": [4, 5, 8], "base": 7, "base_choice_world": [5, 9], "base_task": [5, 9], "base_url": 4, "basechoiceworld": 0, "basesess": [5, 9], "bear": [5, 9], "been": [0, 2, 4, 5, 8, 10, 12], "befor": [2, 4, 5, 8, 10, 11, 14], "behavior": [0, 2, 5, 6, 8, 10, 12], "behaviour": [3, 5, 8], "being": [0, 2], "believ": 4, "belli": [5, 6], "belong": [10, 11], "below": [7, 10, 11, 13, 14], "best": 1, "between": [1, 2, 4, 5, 9], "biasedchoiceworld": [5, 6], "biasedchoiceworldsess": [5, 9], "bin": [5, 6], "bit": 4, "black": [1, 7], "blk": 1, "blue": 1, "bnc": [1, 2], "board": [1, 2], "bodi": [10, 14], "bonsai": [0, 4, 10, 14], "bonsai_workflow": [10, 14], "both": [0, 7, 10, 12, 14], "bottom": 1, "box": 0, "bpod": [0, 1, 3, 5, 6, 8, 9, 10, 11], "brain": [4, 10, 11, 13], "branch": [1, 4, 7], "break": [4, 7], "bright": 1, "bug": [3, 4], "bugfix": [0, 7], "build": 3, "bundl": 1, "button": [0, 1, 4, 10, 11], "c": [1, 2, 3, 5, 8, 9, 10, 11, 12, 13, 14], "cabl": [1, 2], "calibr": [0, 1], "call": [0, 10, 12, 14], "camera": [0, 3, 5, 6, 10, 14], "camera_record": [1, 10, 14], "camera_setup": [10, 14], "can": [1, 2, 5, 6, 7, 8, 9, 10, 13, 14], "cannot": [2, 5, 6], "capabl": 2, "carandiniharris_midbrain_ibl": [5, 6], "card": [1, 2], "case": [0, 5, 9], "catastroph": 2, "caus": [0, 1, 2], "cd": [4, 10, 11, 13, 14], "center": 0, "certain": 4, "cf": 2, "chang": [0, 1, 5, 7, 9, 10, 11], "changelog": [3, 7], "channel": [5, 6], "check": [0, 1, 3, 7, 10, 11], "check_audio_pre_tri": [5, 8], "check_correct_trial_event_sequ": [5, 8], "check_detected_wheel_mov": [5, 8], "check_error_trial_event_sequ": [5, 8], "check_errorcue_delai": [5, 8], "check_gocue_delai": [5, 8], "check_iti_delai": [5, 8], "check_n_trial_ev": [5, 8], "check_negative_feedback_stimoff_delai": [5, 8], "check_positive_feedback_stimoff_delai": [5, 8], "check_response_feedback_delai": [5, 8], "check_response_stimfreeze_delai": [5, 8], "check_reward_volum": [5, 8], "check_reward_volume_set": [5, 8], "check_stimfreeze_delai": [5, 8], "check_stimoff_delai": [5, 8], "check_stimoff_itiin_delai": [5, 8], "check_stimon_delai": [5, 8], "check_stimon_gocue_delai": [5, 8], "check_stimulus_move_before_gocu": [5, 8], "check_trial_length": [5, 8], "check_wheel_freeze_during_quiesc": [5, 8], "check_wheel_integr": [5, 8], "check_wheel_move_before_feedback": [5, 8], "check_wheel_move_during_closed_loop": [5, 8], "checklist": 3, "checkout": 4, "child": [5, 6, 9], "choic": [0, 2], "choiceworldtri": [5, 9], "choiceworldtrialstimelin": [5, 6], "chrono": [5, 6], "ci": [0, 7], "class": [5, 7, 9], "clean": [0, 11], "cleanup": [10, 12], "cli": [0, 10, 11, 14], "click": [1, 4, 5, 7, 8, 10, 11], "clock": [5, 6, 8], "clone": 4, "close": [0, 10, 11], "code": [0, 5, 7, 8, 9], "collect": [1, 5, 6, 10, 12], "color": [0, 5, 8], "com": [2, 4, 10, 13], "com_sound": 2, "combin": [0, 5, 7, 9], "combinatori": [5, 9], "come": [1, 2, 5, 9], "command": [0, 3, 4, 5, 8, 9], "commandlin": 7, "commit": [1, 7], "common": [1, 5, 6], "commun": 2, "compat": [0, 4, 7], "complain": 1, "complet": [4, 5, 6, 10, 11, 12], "complic": [5, 9], "compon": [0, 2], "compos": [5, 9], "comprehens": 1, "comput": [0, 1, 2, 3, 4, 5, 6, 8, 12, 13], "comx": 2, "concern": 2, "conclud": [5, 9], "condit": 0, "configur": [1, 3, 5, 9, 10, 11, 13, 14], "confirm": [10, 11, 12], "conform": [2, 7], "connect": [0, 1, 2, 5, 9, 10, 11], "connector": 2, "consecut": [5, 6], "consolid": 0, "construct": [10, 11], "constructor": [5, 9], "consum": 2, "contact": 1, "contain": [5, 6, 10, 12], "content": [5, 6, 7], "context": 4, "conting": 0, "continu": [2, 4], "contrast": 0, "contribut": [5, 8], "control": [0, 1, 4, 7], "convent": [5, 6, 9], "convert_ui": 0, "copi": [0, 3, 4, 5, 6, 8], "corner": 1, "correct": [0, 1, 4], "correctli": 1, "correspond": [5, 7, 8], "corrupt": 0, "count": [5, 9], "cover": [0, 5, 9], "coverag": 7, "cp": 4, "crash": 0, "creat": [4, 7, 10, 11, 12], "creation": [0, 10, 12], "credenti": [10, 11], "criteria": [0, 5, 8], "critic": [5, 8], "cue": 2, "current": [1, 7, 10, 11], "custom": [3, 8], "custom_task": 0, "damag": 1, "daq": [5, 8], "dark": 1, "data": [0, 5, 6, 8, 14], "databas": [5, 9, 10, 11], "dead": 0, "debug": 0, "decent": 4, "decid": 2, "decim": 0, "dedic": 2, "deem": 7, "deeper": [5, 9], "def": [5, 9], "default": [4, 5, 6, 8, 10, 12, 14], "defin": [0, 5, 6, 8, 10, 11], "delai": 0, "delay_sec": 0, "deleg": 0, "delet": [0, 10, 12], "deliv": 2, "depend": [0, 2, 3], "describ": [3, 7, 10, 13], "descript": [0, 9, 10, 12], "description_ephyspc": [10, 12], "description_taskpc": [10, 12], "design": [2, 10, 11], "desir": [4, 10, 11], "detail": [5, 6, 7], "detect": [0, 1], "determin": [4, 5, 6], "dev": [7, 10, 11], "develop": [1, 3], "devic": [1, 2, 10, 14], "device_camera": [10, 14], "device_sound": [0, 2], "diagram": [5, 7, 8], "dialog": 0, "differ": [1, 10, 12], "digit": [2, 4], "direct": 1, "directli": [10, 11], "directori": [4, 7, 10, 12, 13, 14], "dirti": [0, 7], "disabl": 0, "disconnect": 2, "discov": [4, 7], "discuss": [10, 11], "disk": [5, 9], "displai": [0, 1, 5, 7, 8, 10, 11, 13], "display_idx": 1, "distinct": [5, 9, 10, 11], "distribut": [1, 5, 9], "do": [0, 1, 2, 7], "doc": [0, 7], "document": [0, 5, 8, 10, 13], "doe": [1, 2, 7, 10, 11], "doesn": [10, 12], "don": [0, 1, 4], "done": [5, 8], "dot": 7, "doubl": [1, 5, 9], "down": [0, 2, 10, 11], "downgrad": 4, "download": 4, "draw": [0, 5, 9], "draw_quiescent_period": [5, 9], "drawback": 2, "drive": [5, 9], "driver": [1, 2], "drop": 0, "dry": [10, 12], "dud": 0, "due": 0, "durat": [5, 9], "dure": [0, 1, 2, 5, 6, 9], "dynam": 1, "e": [4, 5, 6, 7, 8, 10, 12, 14], "each": [5, 6, 7, 8, 9, 10, 12, 14], "earlier": 4, "eas": 0, "easi": [5, 9], "easili": [1, 5, 8], "edit": 4, "editor": [0, 2, 4], "effect": 2, "eid": [5, 8], "electr": 1, "electrophysiologi": [5, 6, 10, 13], "emploi": 1, "empti": [10, 12], "emul": 2, "enabl": [5, 8, 10, 11], "encod": [0, 5, 9], "encompass": [10, 11], "end": [0, 1, 2, 5, 9], "enhanc": [10, 11], "enough": 1, "ensur": [1, 4], "enter": [10, 11], "entri": [0, 5, 9], "env": [4, 5, 8], "environ": [4, 10, 11], "ephi": [0, 2, 5, 6, 10, 11, 12, 13, 14], "ephyspc": [10, 12], "ephysrig_setupcamera": [10, 14], "equal": [10, 11], "equip": 2, "errand": [5, 9], "error": [0, 1], "essenti": [5, 8], "establish": [5, 9], "et": [5, 9], "etc": [10, 14], "ethernet": 2, "event": [0, 5, 8, 9], "eventu": 7, "ex": [1, 4], "exampl": [0, 4, 6, 8, 13, 14], "except": 0, "execut": [1, 4, 5, 9, 10, 11, 12], "executionpolici": 4, "exist": [0, 2, 5, 7, 9, 10, 12], "exit": [0, 4], "exp": [5, 9], "expect": [5, 8, 10, 14], "experi": [3, 9, 12, 14], "experienc": 2, "experiment": [5, 9], "explor": 4, "explos": [5, 9], "extens": [1, 5, 6], "extra": 0, "extra_pars": [5, 9], "extract": [5, 6, 8, 9], "extractor": [4, 5, 6, 9], "extractor_task": [5, 9], "face": 1, "factor": [5, 9], "fail": [0, 5, 8], "failur": 2, "fals": 0, "faulti": 1, "featur": [0, 3, 7, 10, 11], "fetch": [0, 4], "few": [1, 5, 9], "fiber": [5, 6], "fidel": 2, "field": [0, 7, 10, 11], "file": [0, 7, 9, 10, 11, 12, 13, 14], "filenam": [0, 10, 12], "filepath": 4, "filter": [10, 11], "final": [2, 5, 8, 9], "find": [2, 5, 8], "fine": [1, 2], "finicki": 1, "finish": 0, "finit": 2, "first": [3, 4, 5, 7, 9], "fix": [0, 7], "flag": [0, 7, 10, 11, 12], "flake8": 0, "flash": 1, "flathead": 2, "flexibl": [5, 9], "flir": 1, "folder": [5, 6, 7, 9, 10, 12, 13], "folder_not_in_desc_fil": [10, 12], "follow": [1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12], "fool": [5, 9], "forc": [0, 4], "forecast": [5, 9], "format": [0, 3, 5, 6], "found": [4, 5, 6, 7, 8, 10, 13], "fp": [5, 6, 10, 14], "frame": [10, 14], "frame2ttl": [0, 3], "framework": [5, 9], "free": 0, "freez": 0, "freeze_reward": 0, "frequent": 3, "friendli": [10, 11], "from": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "front": 1, "ftp": 4, "full": [5, 9], "fulli": [5, 6, 9, 10, 12], "function": [5, 9, 10, 11], "further": [2, 7], "g": [5, 6, 10, 12, 14], "gain": 0, "garbor": 0, "gener": [0, 5, 7, 9], "gentli": 1, "get": [0, 1, 5, 8, 10, 13], "get_task_argu": [5, 9], "git": [4, 7], "github": [1, 4, 7, 10, 11, 13], "give": [5, 6], "given": [5, 6, 8, 10, 12], "glob": 0, "gnd": 1, "go": [5, 9], "googledr": 1, "grade": 2, "green": [5, 8], "guarante": 2, "gui": [0, 5, 9, 10, 11, 13], "guid": [3, 10, 11], "guidelin": 1, "ha": [0, 2, 4, 5, 9], "halt": [5, 9], "hand": 1, "handl": [0, 7], "happen": [5, 9], "happi": [10, 11], "hard": 2, "hardwar": [0, 3, 5, 9], "hardware_set": [0, 1, 2, 4, 10, 14], "hardware_settings_templ": 4, "harp": [1, 2], "have": [1, 2, 4, 5, 6, 8, 10, 11, 12], "haven": 0, "hd": 2, "hear": 2, "height": [5, 6, 10, 14], "help": [1, 5, 8, 10, 12], "here": [1, 4, 5, 6, 7, 8, 9], "hesit": [1, 4], "hierarch": [5, 9], "hifi": [0, 3], "high": 2, "hint": 0, "histori": 0, "hoferlab": 0, "hold": 1, "hood": 0, "host": 1, "hot": 0, "hotfix": 0, "hover": [5, 8], "how": [10, 12, 13, 14], "howev": [4, 5, 9], "html": [4, 7], "htmlcov": 7, "http": [4, 10, 13], "hz": [10, 14], "i": [0, 1, 2, 4, 6, 7, 9, 10, 11, 12, 13, 14], "ibl": [2, 5, 9, 10, 11], "ibl_mesoscope_act": [5, 6], "ibl_neuropixel_brainwide_01": [5, 6], "iblenv": 4, "ibllib": [5, 8], "iblrig": [0, 1, 2, 5, 7, 8, 9, 11, 12, 13, 14], "iblrig_custom_task": [5, 9], "iblrig_param": 4, "iblrig_set": [4, 10, 11, 12, 13, 14], "iblrig_settings_templ": 4, "iblrig_task": [7, 10, 11], "iblrigv8": [1, 2, 3, 7, 11, 12, 14], "iblrigv8_data": [5, 8], "iblrigv8dev": 7, "iblutil": 0, "id": 0, "ideal": 1, "ident": 2, "identifi": [1, 2, 5, 9, 10, 12], "ignor": [0, 7, 10, 12], "imag": [5, 6], "imped": 2, "implement": [0, 5, 7, 8, 9], "import": [4, 5, 6, 9], "improv": [0, 4], "includ": [5, 6, 7, 9, 10, 12], "include_launch": 4, "include_test": 4, "incompat": 7, "incomplet": [4, 10, 12], "inconsist": 0, "incorrect": 0, "increas": 2, "increasingli": 2, "increment": 7, "independ": [10, 12], "index": [7, 10, 14], "indic": [1, 7, 10, 12], "individu": 2, "infer": 7, "info": [5, 8], "inform": [5, 6, 8, 10, 11, 12, 13], "infrastructur": [5, 9], "initi": [0, 5, 9, 10, 11, 12, 13, 14], "input": 1, "inspect": [5, 8], "instal": [0, 3, 5, 9, 11, 13], "install_pyspin": [4, 10, 14], "install_spinnak": [0, 4, 10, 14], "installallus": 4, "instanc": [5, 7, 9, 10, 11], "instanti": [5, 9], "instead": [0, 1], "instruct": [0, 3, 10, 13], "int": [4, 10, 13], "integ": 0, "integr": [5, 8], "interact": 7, "interfac": [0, 5, 9], "intermitt": 1, "intern": [10, 11], "internationalbrainlab": 4, "internet": [0, 4], "intervent": 2, "introduc": [0, 2], "invalu": 1, "investig": [5, 8], "invok": [4, 5, 9], "involv": [5, 9], "io": 4, "ipad": 1, "ipython": 4, "issu": [0, 2, 3, 7, 10, 11], "item": 4, "itemtyp": 4, "iterate_protocol": 0, "its": [1, 2, 10, 12], "itself": 2, "john": [10, 11], "json": 4, "junk": 0, "just": [10, 13], "keep": 4, "kei": [4, 5, 6, 10, 12, 14], "keyboard": 4, "know": [5, 8], "ks022": [5, 8], "kwarg": [5, 9], "lab": [0, 4, 5, 6, 7, 10, 11, 12, 13], "label": [1, 2], "laboratori": [10, 11], "last": 7, "latenc": 2, "later": 0, "latest": [2, 7], "latter": [2, 4], "launch": [5, 9, 10, 11, 13], "layout": 0, "lead": [5, 9], "least": [1, 5, 6, 8], "leav": 2, "led": 0, "left": [5, 6, 8, 9, 10, 14], "legend": 0, "less": 0, "level": [0, 4], "leverag": [5, 9], "lifetim": [5, 9], "light": 1, "like": [4, 5, 9], "limit": 0, "line": [0, 4, 5, 8, 9], "link": [10, 11], "lint": [0, 3], "list": [0, 4, 5, 6, 10, 11], "live": 0, "local": [0, 3, 4, 5, 8, 9, 13, 14], "locat": [5, 9], "log": [0, 5, 9], "logic": [5, 8, 9], "login": [10, 11], "long": 1, "longer": 2, "look": [1, 5, 9], "loop": [5, 9], "loos": 1, "lost": 0, "low": 2, "lower": 0, "lpt": 2, "m": [1, 3, 7], "machin": [0, 1, 2], "made": [5, 9], "mai": [1, 4, 7], "main": [1, 5, 6], "mainten": 0, "major": [0, 7], "make": [0, 1, 2, 5, 7, 9, 10, 11, 13], "manag": 2, "mandatori": [10, 11], "mani": [5, 6], "manner": 4, "manual": [1, 2, 7, 10, 11], "map": [5, 6], "master": 7, "match": [1, 5, 8], "max_": [5, 9], "maximum": [5, 9], "md": [5, 7, 9], "mean": [4, 5, 7, 8, 9], "mention": [10, 11], "menu": [0, 1, 4, 5, 8], "merg": [7, 10, 12], "mesoscop": [2, 5, 6], "messag": 0, "metadata": [5, 6], "method": [0, 5, 9], "micro": 2, "microphon": [0, 5, 6], "microsoft": 4, "might": 1, "min_": [5, 9], "minor": [0, 7], "minut": 2, "misc": [5, 9], "misconfigur": 2, "miss": 0, "mix": 2, "mixin": [5, 9], "mkdir": 7, "mm": 2, "mock": 0, "modal": [5, 9], "mode": [0, 4], "model": 1, "modif": [5, 9], "modifi": [5, 9], "modul": [0, 3, 5, 9], "modular": 0, "molex": 1, "more": [0, 2, 5, 8, 10, 11, 12, 13], "most": [1, 5, 9], "mount": 1, "mous": [5, 8], "move": 0, "multipl": [0, 5, 9, 10, 14], "must": [4, 5, 6, 10, 11, 14], "name": [0, 5, 6, 8, 9, 10, 12, 14], "narrow": [10, 11], "navig": [10, 12, 13], "nb": [10, 12], "necessari": [1, 10, 11], "need": [0, 2, 4, 7, 10, 11, 12], "neg": 0, "neither": 1, "neuropixel": [3, 5, 6], "new": [0, 4, 5, 7, 9], "newest": 4, "next": [4, 7], "nidq": [5, 6], "nm": 0, "non": [0, 5, 8], "nonewwindow": 4, "nor": 1, "norestart": 4, "not_set": [5, 8], "note": [1, 10, 11, 12], "notebooks_extern": 4, "notepad": 4, "notic": 0, "notif": 0, "notori": 1, "now": [0, 4, 5, 9], "npy": [5, 6], "number": [5, 6, 7], "o": 7, "object": 0, "occur": 1, "off": 1, "offer": [0, 1], "offset": [0, 5, 9], "often": 4, "old": [10, 12], "older": [2, 4, 10, 12], "olivier_awesomechoiceworld": [5, 9], "omit": [10, 12], "onboard": 1, "onc": [0, 10, 12], "one": [1, 2, 4, 5, 6, 8, 10, 12], "one_quickstart": 4, "onli": [0, 2, 5, 6, 7, 9], "onlin": 0, "ons": [5, 9], "onto": 7, "open": [1, 2, 4, 10, 11, 12, 13, 14], "optic": [5, 6], "option": [0, 1, 4, 5, 6, 9, 10, 11, 12, 14], "optostim": 0, "order": [5, 6, 10, 12], "org": 4, "origin": [1, 2, 7], "oscilloscop": 1, "other": [1, 2, 4, 5, 6], "our": [1, 2, 5, 9], "out": [0, 1, 4], "outfil": 4, "output": [1, 2, 7], "outsid": 0, "over": [1, 5, 8, 10, 12], "overal": [5, 8], "overflow": 0, "overload": [5, 9], "overview": [5, 8, 10, 14], "overwritten": 0, "p": 7, "packag": [0, 4, 10, 13], "page": [5, 8], "panel": [5, 8], "paramet": [0, 4, 5, 9, 10, 14], "parent": [5, 6, 9], "parlanc": [5, 9], "pars": 0, "part": [5, 8], "particip": [10, 11], "particular": [10, 12], "particularli": 2, "pass": [0, 4, 5, 6, 8, 10, 14], "passiv": [0, 4, 10, 11], "passivechoiceworld": [0, 5, 6], "passiveregisterraw": [5, 6], "passivetasktimelin": [5, 6], "password": 4, "patch": [0, 7], "path": [0, 4, 5, 8], "pc": [1, 5, 8, 10, 12], "per": [0, 1, 5, 6], "perform": [5, 9], "period": [0, 5, 9], "person": 4, "pertin": [10, 11], "photometri": [5, 6], "piec": [1, 2], "pin": 0, "pip": [4, 7, 10, 13], "pipelin": [2, 5, 6], "place": 1, "plai": 1, "plastic": 1, "pleas": [4, 10, 11], "plot": 0, "plug": [1, 2], "png": 7, "point": [0, 2, 4, 5, 9], "polar": 1, "polici": [4, 5, 9], "popul": [0, 10, 11], "port": [0, 1, 2], "portabl": 4, "posit": 0, "possibl": [0, 1, 5, 6, 9, 10, 11], "post": 3, "post3": 7, "potenti": 2, "power": 1, "powershel": [0, 1, 3, 10, 11], "pr": [0, 7], "pragma": [5, 9], "pre": 7, "preced": [10, 11], "prefer": 1, "prepar": 3, "presenc": 7, "present": 0, "press": [4, 10, 11], "prevent": 1, "preview": 1, "previou": [0, 7], "prior": [5, 9], "probe": [5, 6, 10, 13], "problem": [0, 2], "problemat": [5, 8], "proce": 0, "procedur": [10, 11], "process": 4, "produc": 2, "program": 4, "progress": [10, 11], "project": [4, 9, 10, 11], "project_extract": [4, 5, 9], "prompt": [0, 4], "proper": [0, 2], "properli": [5, 8], "proport": [5, 8], "protocol": [0, 5, 6, 8, 9], "protocol_nam": [5, 9], "provid": [1, 5, 9, 10, 11], "prune": 4, "ps1": [1, 4, 10, 11, 12, 13, 14], "pt": 0, "pull": [4, 7], "puls": [2, 5, 6], "purpos": [10, 11], "push": 7, "py": [5, 7, 9, 10, 11, 12, 13, 14], "pyrevers": 7, "pyspin": [0, 4, 10, 14], "pytest": 7, "python": [3, 7, 10, 11], "python310": 4, "qc": [10, 14], "qt": 0, "qualiti": 3, "question": 3, "quiescenc": [0, 5, 9], "quiet": 4, "race": 0, "rais": 0, "random": [5, 9], "rate": [1, 10, 14], "raw_behavior_data": [5, 6], "raw_ephys_data": [5, 6, 10, 12], "raw_imaging_data": [5, 6], "raw_sess": [10, 12], "raw_sync_data": [5, 6], "raw_task_data_00": [5, 6, 10, 12], "raw_task_data_01": [5, 6], "raw_video_data": [5, 6], "rca": 2, "re": [0, 1], "reach": [4, 5, 9], "read": [0, 5, 9, 10, 12], "readm": [5, 9], "realiz": [5, 9], "reason": 2, "reboot": 1, "recalibr": 1, "receiv": 1, "recommend": [4, 10, 14], "record": [1, 3, 5, 6, 9, 14], "redefin": 1, "redistribut": 3, "refer": [3, 7], "reference_developer_guid": 5, "reformat": 7, "regard": [1, 5, 8], "regardless": [5, 8], "regex": 0, "regist": 0, "registr": [5, 8], "relat": [5, 9], "relationship": [5, 6], "releas": [0, 3, 4], "relev": [10, 12], "reli": 2, "reliabl": 0, "remain": [1, 10, 12], "rememb": 0, "remot": [0, 4, 10, 12, 13, 14], "remotesign": 4, "remov": [0, 5, 9, 10, 12], "repair": 0, "replac": [2, 5, 9], "replug": 1, "report": [3, 4, 7], "reposit": 1, "repositori": [0, 5, 7, 9], "request": [3, 7], "requir": [1, 4, 5, 7, 9, 10, 14], "requisit": 7, "resolut": [10, 14], "resolv": 1, "respect": [0, 1, 2, 10, 12], "respons": 1, "restart": 1, "restrict": 4, "restructur": 0, "result": [2, 4, 5, 9], "retriev": 4, "return": [0, 4, 5, 8, 9], "revers": 0, "revert": 0, "reward": 0, "rework": 0, "rewritng": [5, 9], "rf": 7, "ribbon": 1, "rig": [0, 1, 2, 5, 8, 9, 10, 11], "right": [1, 4, 5, 6, 8, 10, 14], "rise": 2, "rj45": 2, "rm": 7, "robust": [0, 2], "rollback": [0, 2], "root": [5, 9], "rotari": [0, 5, 9], "routin": [0, 1], "rst": [5, 7], "rsync": [10, 12], "ruff": [0, 7], "run": [0, 1, 3, 6, 9, 12, 14], "safe": 7, "same": [5, 6], "sanwork": 2, "sata": 1, "save": [1, 5, 9, 10, 12], "scale": 0, "scheme": 3, "scrambl": 0, "screen": [0, 3], "screenshot": [10, 11], "screwdriv": 2, "script": [0, 1, 4, 11, 13, 14], "sdk": [0, 4], "seamless": 4, "search": 4, "seat": 1, "sec": [5, 9], "second": [0, 1, 4], "section": [2, 4, 5, 6, 10, 12], "secur": [1, 4], "see": [1, 4, 5, 8, 10, 12], "seem": 2, "select": [4, 5, 7, 8, 10, 11], "self": [5, 9], "semant": 7, "send": 1, "sensor": [0, 1], "separ": [0, 7, 10, 12, 14], "sequenc": [5, 8, 9, 10, 11], "serial": [0, 2], "serialsingleton": 0, "serv": [7, 10, 11], "server": [0, 4, 5, 6, 9, 10, 12, 13, 14], "sess": [5, 9], "session": [0, 1, 2, 9, 10, 12], "sessioncopi": 0, "set": [0, 1, 2, 5, 6, 9, 11, 12, 13], "setup": [0, 4], "sever": 2, "shape": 1, "shell": 4, "shorter": 1, "should": [1, 2, 4, 5, 8, 9, 10, 14], "show": [0, 1, 2, 10, 13, 14], "shown": [10, 11], "side": [0, 7], "sig": 1, "sigint": [5, 9], "sign": 4, "signal": [1, 2], "signatur": 4, "silent": 4, "simpli": [10, 14], "sinc": 2, "singl": 1, "singleton": 0, "situat": 1, "skip": [0, 10, 12], "slack": [10, 11], "slip": 1, "small": 0, "snapshot": 0, "so": 7, "softwar": [5, 6, 10, 13, 14], "some": [4, 5, 8, 9], "sound": [2, 3, 5, 9], "soundcard": [1, 2], "sourc": [0, 4, 7, 10, 12], "specif": [0, 1, 2, 3, 5, 6, 9], "specifi": [5, 6, 10, 12], "sphinx": 7, "spikeglx": [5, 6], "spinnak": [0, 4, 10, 14], "split": 0, "standard": 2, "start": [0, 1, 2, 4, 5, 9, 12], "start_ephys_sess": [10, 13], "start_video_sess": [10, 14], "state": [0, 2, 10, 12], "static": 7, "statu": [0, 10, 12], "step": [0, 1, 2, 4, 5, 9], "stick": 1, "still": [4, 10, 11], "stim_revers": 0, "stimul": [5, 6], "stimuli": 2, "stimulu": 0, "stock": [10, 11], "stop": 1, "store": [5, 6], "straightforward": 2, "stream": [5, 8], "strike": 4, "string": [0, 7], "structur": [5, 9], "stub": [10, 12], "style": 7, "sub": [5, 6], "subfold": [10, 12], "subject": [0, 2, 5, 8, 10, 11, 12, 13, 14], "submit": 4, "subprocess": 0, "success": [10, 12], "suffici": 1, "suggest": [10, 11], "super": [5, 9], "suppli": 1, "support": [0, 2, 5, 6], "sure": [0, 1, 2, 5, 7, 9, 10, 13], "swap": 1, "swiftli": [10, 11], "switch": [0, 1, 3], "sync_label": [5, 6], "synchron": 2, "synchronis": [5, 6], "sysdefault": 1, "system": [1, 4], "systemat": [10, 12], "t": [0, 1, 4, 10, 12], "tab": [0, 1], "tabl": 7, "tag": [0, 4, 7, 10, 12, 13, 14], "take": [2, 5, 8], "talk": [5, 9], "tape": 1, "target": 0, "task": [0, 1, 3, 4, 7, 12], "task_paramet": [5, 9], "task_qc": [5, 8], "taskpc": [10, 12], "taskqc": [5, 8], "tdm": [5, 6], "team": [1, 10, 11], "temp": 4, "templat": 4, "temporari": 4, "temporarili": 0, "termin": [10, 11, 12, 13, 14], "test": [0, 1, 3, 5, 8], "test_olivier_awesomechoiceworld": [5, 9], "texp": [5, 9], "text": [2, 4], "than": [0, 2, 10, 12], "thei": [5, 8, 9], "them": [2, 4], "therefor": [5, 6], "thi": [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], "third": 7, "those": [5, 9], "thread": 0, "three": [7, 10, 12], "through": [0, 1, 5, 9, 10, 11, 12], "throw": 0, "tie": 1, "tightli": 1, "time": [0, 2, 5, 8], "timelin": [0, 5, 6], "timeseri": [5, 6], "timestamp": [5, 6], "toggl": [10, 11], "tool": [0, 1], "track": 1, "train": [0, 2, 10, 14], "trainingchoiceworld": 0, "trainingcw": 0, "trainingphasechoiceworld": 0, "trainingrig_savevideo_trainingtask": [1, 10, 14], "trainingstatu": [5, 6], "tranfer_data": [10, 12], "transfer": [0, 1, 5, 9, 10, 12, 13, 14], "transfer_data": [0, 10, 12, 13, 14], "transit": 0, "trial": [0, 5, 8, 9], "trialregisterraw": [5, 6, 9], "trigger": [0, 5, 7, 9], "trivial": [5, 9], "truncat": [5, 9], "trust": 4, "try": 1, "ttl": [0, 1, 2, 5, 6], "two": [4, 5, 6, 10, 11], "type": [0, 4, 10, 11, 12, 13, 14], "typic": [5, 9], "u": [1, 5, 7, 9], "uncommit": 7, "under": [0, 10, 12], "underscor": [5, 9], "unfil": 0, "unfold": [5, 9], "unicod": 0, "uniqu": [5, 6], "unit": [0, 1, 3], "unittest": [4, 7], "unlik": [5, 8], "unnecessari": 0, "unobtrus": 4, "unplug": [1, 2], "unreli": 0, "unscrew": 2, "unus": 0, "unvers": 7, "up": [0, 1, 2], "updat": [0, 2, 3, 7], "upgrad": [0, 3, 4, 7], "upon": [5, 7, 9, 10, 11, 12], "upper": 0, "uri": 4, "url": [0, 4, 10, 11], "us": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14], "usabl": [0, 4, 10, 11], "usag": 3, "usb": [1, 2], "usb2": 1, "usb3": 1, "user": [0, 1], "usernam": [4, 10, 11], "userprofil": 4, "usual": [0, 1], "util": [10, 11], "v": 4, "v1": 0, "v7": [0, 7], "v8": [3, 7, 11], "valid": [0, 1, 2], "validate_iblrig": 1, "validate_video": 0, "valu": [1, 4, 5, 8, 10, 11], "valv": 0, "variabl": 7, "variant": [5, 9], "variat": 1, "variou": 0, "vc_redist": 4, "vcredist_x64": 4, "ve": 2, "venv": [1, 4, 7, 10, 11, 12, 13, 14], "veri": [5, 6], "verifi": [1, 2, 5, 8, 10, 12], "version": [0, 1, 2, 3], "version_manag": 0, "via": [1, 2], "video": [0, 1, 3, 12], "view": [0, 10, 12], "viewephi": [10, 13], "virtual": 4, "visibl": [5, 9], "visual": [0, 3, 10, 13], "visualis": [5, 8], "voil\u00e0": [5, 9], "voltag": 1, "volum": 2, "vsu_4": 4, "wa": [2, 5, 6, 10, 12], "wai": [0, 2], "wait": [0, 4, 7], "want": [5, 9], "warn": [0, 2, 5, 8], "water": [0, 5, 9], "we": [1, 2, 5, 9, 10, 11], "weak": 2, "webpag": [5, 8], "webrequest": 4, "websit": 7, "week": [10, 12], "weight": 0, "well": 2, "wet": 7, "what": [5, 9], "wheel": [0, 4], "when": [0, 1, 5, 8, 9, 10, 14], "where": 0, "whether": [5, 8], "which": [4, 5, 6, 7, 8, 9, 10, 11, 14], "while": [2, 4], "white": 1, "whole": [5, 9], "wht": 1, "why": [5, 8], "widefield": [5, 6], "width": [5, 6, 10, 14], "window": [1, 2, 3, 10, 11], "windowspath": 0, "wire": [1, 2], "wish": [10, 13], "within": [5, 7, 8, 9, 10, 14], "without": [0, 1, 4, 5, 8, 10, 11, 12], "wizard": [0, 10, 11], "won": [1, 10, 12], "work": [0, 1, 2, 4, 7, 10, 11], "worker": 0, "workflow": [0, 1, 7, 14], "world": 0, "write": [7, 8], "wrong": 0, "www": 4, "x64": 4, "xonar": [1, 3], "y": [0, 7], "yaml": [0, 1, 2, 4, 5, 6, 9, 10, 12, 14], "yet": [5, 8], "you": [1, 2, 5, 7, 8, 10, 11, 13], "your": [1, 2, 4, 7, 8, 10, 11, 12], "your_password": 4, "your_usernam": 4, "zapit": 0, "zip": 1}, "titles": ["Changelog", "Frequently Asked Questions", "Hardware Guide", "IBLRIG documentation", "Installation guide", "Reference", "Describing an Experiment", "Developer Guide", "Quality check the task post-usage", "Guide to develop a custom task", "Using IBLRIG v8", "Running a behaviour experiment", "Copy commands", "Neuropixel recording with iblrigv8", "Video acquisition computer"], "titleterms": {"0": 0, "1": [0, 5, 9], "10": [0, 4], "11": 0, "12": 0, "13": 0, "14": 0, "15": 0, "16": 0, "17": 0, "18": 0, "19": 0, "2": [0, 5, 9], "20": 0, "3": [0, 4], "4": 0, "5": 0, "6": 0, "7": 0, "8": 0, "9": 0, "ONE": 4, "The": [10, 11], "acquir": [5, 8], "acquisit": [10, 14], "ae": 2, "after": [5, 8], "aid": 1, "alyx": [4, 5, 8, 10, 11], "an": [5, 6], "ask": 1, "background": [2, 4], "behaviour": [10, 11], "behind": [10, 12], "bias": [5, 9], "bonsai": 1, "bpod": 2, "break": [5, 6], "bug": 1, "build": 7, "c": 4, "camera": 1, "can": 4, "chain": [10, 11], "changelog": 0, "check": [4, 5, 8], "checklist": 7, "choic": [5, 9], "clean": [10, 12], "command": [10, 11, 12, 13, 14], "compon": [5, 6], "comput": [10, 14], "config": [10, 14], "configur": 4, "connect": 4, "content": 3, "contribut": 7, "control": [10, 11], "copi": [10, 12, 13, 14], "creat": [5, 9], "custom": [5, 9], "data": [10, 12, 13], "default": 1, "defin": 1, "definit": [5, 8], "depend": 7, "describ": [5, 6], "descript": [5, 6], "design": [5, 9], "develop": [5, 7, 9], "devic": [5, 6], "document": [3, 7], "down": [5, 6], "driver": [10, 14], "everyth": 4, "exampl": [5, 9, 10, 12], "experi": [5, 6, 10, 11], "featur": 1, "file": [4, 5, 6], "fine": 4, "first": 1, "flush": [10, 11], "format": 7, "frame2ttl": 1, "frequent": 1, "gener": 1, "graphic": [10, 11], "guid": [2, 4, 5, 7, 9], "hardwar": 2, "hifi": 2, "how": [5, 8], "i": [5, 8], "iblrig": [3, 4, 10], "iblrigv8": [4, 5, 9, 10, 13], "immedi": [5, 8], "inherit": [5, 9], "instal": [4, 7, 10, 14], "instruct": 4, "interfac": [10, 11], "issu": 1, "level": [5, 8], "line": [10, 11], "lint": 7, "local": [7, 10, 12], "look": [10, 13], "m": 4, "machin": [5, 9], "make": 4, "metric": [5, 8], "modul": 2, "neuropixel": [10, 13], "onc": [5, 8], "outcom": [5, 8], "own": [5, 9], "posit": 1, "post": [5, 8], "powershel": 4, "prepar": 4, "prerequisit": 4, "procedur": [2, 5, 6], "project": [5, 6], "python": 4, "qc": [5, 8], "qualiti": [5, 8], "quantifi": [5, 8], "question": 1, "raw": [10, 13], "re": [5, 9], "record": [10, 13], "redistribut": 4, "refer": 5, "regist": [5, 8], "releas": 7, "report": 1, "request": 1, "requir": 2, "rig": 4, "run": [4, 5, 7, 8, 10, 11], "scheme": 7, "screen": 1, "script": [10, 12], "session": [5, 8], "set": [4, 10, 14], "setup": [10, 13, 14], "sever": [10, 11], "singl": [10, 11], "size": 1, "sound": 1, "specif": 4, "start": [10, 11, 13, 14], "state": [5, 9], "suit": 4, "supplementari": [10, 11], "sure": 4, "switch": 4, "sync": [5, 6], "task": [5, 6, 8, 9, 10, 11, 13, 14], "test": [4, 7], "togeth": [10, 11], "unit": 7, "up": [4, 10, 12], "updat": 4, "upgrad": 2, "us": 10, "usag": [5, 8, 10, 12, 13, 14], "user": [10, 11], "v8": 10, "valv": [10, 11], "variat": [5, 9], "version": [4, 5, 6, 7], "video": [10, 14], "viewer": [5, 8], "visual": [1, 4], "went": 4, "where": [5, 9], "window": 4, "workflow": [10, 12], "world": [5, 9], "write": [5, 9], "xonar": 2, "you": 4, "your": [5, 9]}}) \ No newline at end of file diff --git a/usage.html b/usage.html new file mode 100644 index 000000000..0670549f1 --- /dev/null +++ b/usage.html @@ -0,0 +1,555 @@ + + + + + + + Using IBLRIG v8 — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Using IBLRIG v8

+
+

Running a behaviour experiment

+

IBLRIG v8 provides users with two distinct interfaces: a command line interface (CLI) and a graphical user interface (GUI). +The CLI encompasses the complete functionality of IBLRIG, upon which the GUI is constructed to enhance user-friendliness. +All tasks achievable through the GUI are equally achievable through the CLI.

+
+

The Graphical User Interface

+

To initiate a task through the graphical user interface, open a Windows PowerShell and enter:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+iblrig
+
+
+

These commands activate the necessary environment and launch the IBL +Rig Wizard GUI window, as shown below:

+
+A screenshot of IBL Rig Wizard +
+

A screenshot of IBL Rig Wizard

+
+
+
+

Starting a Task

+
    +
  1. Enter your Alyx username, then click on the Connect button. This +action will automatically populate the GUI fields with information +pertinent to your lab.

  2. +
  3. Select the desired values from the provided options. Utilize the +Filter field to swiftly narrow down the list of displayed subjects. +Note that selections for Project and Procedure are mandatory.

  4. +
  5. Click the Start button to initiate the task.

  6. +
+
+
+

Supplementary Controls

+
    +
  • If you check the Append option before clicking Start, the task +you initiate will be linked to the preceding task, creating a +sequence of connected tasks.

  • +
  • The Flush button serves to toggle the valve for cleaning purposes.

  • +
+
+

Note

+

IBLRIG’s Graphical User Interface is still work-in-progress. If you have any suggestions to make the GUI +more usable, please add an issue on GitHub or approach the dev-team on Slack! +We are happy to discuss possible changes with you!

+
+
+
+
+

Interfacing with Alyx

+

Although this is not mandatory, the IBLRIG GUI is designed to interface with Alyx, the International Brain Laboratory’s database. +This feature allows users to access their subjects and projects directly from the GUI, without the need to manually enter this information.

+

To enable this feature, you must have an Alyx account and have configured your database URL and credentials as mentioned Installation guide.

+
    +
  • The subjects available are the set of alyx subjects that are alive, not stock, and belong to the lab defined in the iblrig_settings.py file.

  • +
  • The projects available are the set of projects of which the current user is a participant. Login to Alyx > Subjects > Projects to check your projects.

  • +
+
+
+

The Command Line Interface

+

To use the command line interface, open a terminal and activate the +environment:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+
+
+
+

Running a single task

+

To run a single task, execute the following command:

+
python .\iblrig_tasks\_iblrig_tasks_trainingChoiceWorld\task.py --subject algernon --user john.doe
+
+
+
+
+

Chaining several tasks together

+

To chain several tasks together, use the --append flag. For +instance, to run a passive task after an ephys task:

+
    +
  1. Run the ephys task

    +
    .\iblrig_tasks\_iblrig_tasks_ephysChoiceWorld\task.py --subject algernon
    +
    +
    +
  2. +
  3. Run the passive task with the --appendflag:

    +
    .\iblrig_tasks\_iblrig_tasks_passiveChoiceWorld\task.py --subject algernon --append
    +
    +
    +
  4. +
+
+
+

Flushing the valve

+

To flush valve 1 of the Bpod, type flush and confirm with ENTER. Press ENTER again to close the valve.

+
+
+
+
+

Copy commands

+
+

Usage

+

To initiate the data transfer from the local server to the remote +server, open a terminal and type.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag behavior
+
+
+

The transfer local and remote directories are set in the +iblrig/settings/iblrig_settings.py file.

+

To copy data at another acquisition PC, such as video and ephys, use the relevant tag, e.g.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag video
+
+
+

NB: By default the local data that was copied over 2 weeks ago will be automatically removed. To +avoid this set the cleanup-weeks argument to -1:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data behavior --cleanup-weeks -1
+
+
+

See the ‘Clean-up local data’ section on how to remove data without calling the copy script.

+

To view the copy status of your local sessions without actually copying, use the ‘dry’ argument:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data behavior --dry
+
+
+

For more information on the tranfer_data arguments, use the help flag:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --help
+
+
+
+
+

Clean-up local data

+

To remove sessions fully copied to the server and older than 2 weeks, +open a terminal and type:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+remove-old-sessions
+
+
+

Note: the server needs to be up and running or the sessions won’t be +verified as copied.

+
+
+

Behind the Copy Scripts

+
+

Workflow

+
    +
  1. Initial Stub Creation: At the start of acquisition, an incomplete +experiment description file - a ‘stub’ - is saved to the session +on, both, the local PC and the lab server in a subfolder called +_devices. The filename of the stub includes the PC’s identifier, +allowing the copy script to identify its source.

  2. +
  3. Executing the Copy Script: The copy script is executed on each +acquisition PC independently and in no particular order.

  4. +
  5. Navigating Local Session Data: The script systematically +navigates through local session folders (or optionally a separate +transfers folder) that contain experiment.description stubs.

  6. +
  7. Skipping Transferred Sessions: The script ignores session folders +containing a file named transferred.flag (see 7).

  8. +
  9. Copying Collections: For each session, the script reads the +respective stub and uses rsync to copy each collection. +Subfolders not specified under a collection key are omitted from +copying.

  10. +
  11. Removing Remote Stubs: Upon successful copying, the remote stub +file is merged with the remote experiment.description file (or +copied over if one doesn’t exist already). The remote stub file is +then deleted.

  12. +
  13. Confirming Transfer Locally: A transferred.flag file is +created in the local session folder to confirm the transfer’s +success.

  14. +
  15. Completion and Cleanup: Once no more remote stub files exist +for a given session, the empty _devices subfolder is removed. +Additionally, a ‘raw_session.flag’ file is created in the remote session folder, +indicating the successful transfer of all files.

  16. +
+
+
+

Example of workflow

+

Example of three sessions each in a different copy state:

+
    +
  • The State on the Remote Lab Server

    +
    lab server/
    +└── subject/
    +    └── 2020-01-01/
    +        ├── 001/
    +        │   └── _devices/
    +        │       ├── 2020-01-01_1_subject@taskPC.yaml
    +        │       └── 2020-01-01_1_subject@ephysPC.yaml
    +        ├── 002/
    +        │   ├── _ibl_experiment.description.yaml
    +        │   ├── raw_task_data_00/
    +        │   └── _devices/
    +        │       └── 2020-01-01_1_subject@ephysPC.yaml
    +        └── 003/
    +            ├── raw_task_data_00/
    +            ├── raw_ephys_data/
    +            ├── _ibl_experiment.description.yaml
    +            └── raw_session.flag
    +
    +
    +
  • +
  • The State on the Local Task Acquisition PC

    +
    acquisition computer (taskPC)/
    +└── subject/
    +    └── 2020-01-01/
    +        ├── 001/
    +        │   ├── raw_task_data_00/
    +        │   └── _ibl_experiment.description_taskPC.yaml
    +        ├── 002/
    +        │   ├── raw_task_data_00/
    +        │   ├── _ibl_experiment.description_taskPC.yaml
    +        │   └── transferred.flag
    +        └── 003/
    +            ├── raw_task_data_00/
    +            ├── folder_not_in_desc_file/
    +            ├── _ibl_experiment.description_taskPC.yaml
    +            └── transferred.flag
    +
    +
    +
  • +
  • +
    The State on the Local Ephys Acquisition PC
    acquisition computer (ephysPC)/
    +└── subject/
    +    └── 2020-01-01/
    +        ├── 001/
    +        │   ├── raw_ephys_data/
    +        │   └── _ibl_experiment.description_ephysPC.yaml
    +        ├── 002/
    +        │   ├── raw_ephys_data/
    +        │   ├── _ibl_experiment.description_ephysPC.yaml
    +        └── 003/
    +            ├── raw_ephys_data/
    +            ├── folder_not_in_desc_file/
    +            ├── _ibl_experiment.description_ephysPC.yaml
    +            └── transferred.flag
    +
    +
    +
    +
    +
  • +
+

With the lab server and acquisition pcs in the states above, the +sessions are in the following states

+
    +
  • subject/2020-01-01/001 no data have been copied.

  • +
  • subject/2020-01-01/002 data from taskPC have been copied, data from ephysPC remains to be copied.

  • +
  • subject/2020-01-01/003 data copied from all acquisition PCs.

  • +
+
+
+
+
+

Video acquisition computer

+

Video can be run on a separate computer, which is recommended when recording multiple cameras.

+
+

Setup

+
+

Installing drivers

+

Both spinnaker and pyspin must be installed before running an experiment:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+install_spinnaker
+install_pyspin
+
+
+
+
+

Settings config

+

The camera acquisition is configured by parameters in the ‘device_cameras’ key of the hardware_settings.yaml file. +Below is an overview of the parameters:

+
device_cameras:
+  # The name of the configuration. This is passed to the CLI.
+  default:
+    # This is required: the Bonsai workflows to be called by the CLI script.
+    BONSAI_WORKFLOW:
+      # Optional setup (e.g. alignment) workflow
+      setup: devices/camera_setup/EphysRig_SetupCameras.bonsai
+      # Required workflow to be called when the experiment starts
+      recording: devices/camera_recordings/TrainingRig_SaveVideo_TrainingTasks.bonsai
+    # Camera #1 name
+    left:
+      # Required camera device index (assigned in driver software)
+      INDEX: 1
+      # Optional expected frame height. Actual resolution should be set in the driver software.
+      HEIGHT: 1024
+      # Optional expected frame width. This is simply used in QC.
+      WIDTH: 1280
+      # Optional expected frame rate (Hz). This is simply used in QC.
+      FPS: 30
+
+
+

Multiple configurations can be added, e.g. ‘default’, ‘training’, ‘ephys’, etc. and within each, multiple cameras +can be added, e.g. ‘left’, ‘right’, ‘body’, etc. Each configuration requires a BONSAI_WORKFLOW: recording key; +each camera requires an INDEX key.

+
+
+
+

Starting a task

+

Below shows how to start the cameras for the subject ‘example’ with configuration ‘default’:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+start_video_session example default
+
+
+
+
+

Copy command

+
+

Usage

+

To initiate the data transfer from the local server to the remote server, open a terminal and type.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag video
+
+
+

The transfer local and remote directories are set in the +iblrig/settings/iblrig_settings.py file.

+
+
+
+
+

Neuropixel recording with iblrigv8

+

This document describes how to use the iblrigv8 software to record from the Neuropixel computer.

+
+

Setup

+

Just make sure iblrigv8 is installed according to the instructions and that the iblrig_settings.py +file is configured with the local folder and remote folder for the data transfer.

+

To get access to the viewephys visualizer:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+pip install viewephys
+
+
+
+
+

Starting a task

+

Below shows how to start the electrophysiology for the subject ‘example’ with 2 probes:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+start_ephys_session example 2
+
+
+
+
+

Copy command

+
+

Usage

+

To initiate the data transfer from the local server to the remote server, open a terminal and type.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag ephys
+
+
+

The transfer local and remote directories are set in the +iblrig/settings/iblrig_settings.py file.

+
+
+
+

Look at the raw data

+

This will launch the viewephys GUI, you can then use file -> open and navigate +to open the raw data file you wish to display.

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+viewephys
+
+
+Alternative text +

More information on the viewephys package can be found at: https://github.com/int-brain-lab/viewephys

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/usage_behavior.html b/usage_behavior.html new file mode 100644 index 000000000..fc09410fa --- /dev/null +++ b/usage_behavior.html @@ -0,0 +1,225 @@ + + + + + + + Running a behaviour experiment — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Running a behaviour experiment

+

IBLRIG v8 provides users with two distinct interfaces: a command line interface (CLI) and a graphical user interface (GUI). +The CLI encompasses the complete functionality of IBLRIG, upon which the GUI is constructed to enhance user-friendliness. +All tasks achievable through the GUI are equally achievable through the CLI.

+
+

The Graphical User Interface

+

To initiate a task through the graphical user interface, open a Windows PowerShell and enter:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+iblrig
+
+
+

These commands activate the necessary environment and launch the IBL +Rig Wizard GUI window, as shown below:

+
+A screenshot of IBL Rig Wizard +
+

A screenshot of IBL Rig Wizard

+
+
+
+

Starting a Task

+
    +
  1. Enter your Alyx username, then click on the Connect button. This +action will automatically populate the GUI fields with information +pertinent to your lab.

  2. +
  3. Select the desired values from the provided options. Utilize the +Filter field to swiftly narrow down the list of displayed subjects. +Note that selections for Project and Procedure are mandatory.

  4. +
  5. Click the Start button to initiate the task.

  6. +
+
+
+

Supplementary Controls

+
    +
  • If you check the Append option before clicking Start, the task +you initiate will be linked to the preceding task, creating a +sequence of connected tasks.

  • +
  • The Flush button serves to toggle the valve for cleaning purposes.

  • +
+
+

Note

+

IBLRIG’s Graphical User Interface is still work-in-progress. If you have any suggestions to make the GUI +more usable, please add an issue on GitHub or approach the dev-team on Slack! +We are happy to discuss possible changes with you!

+
+
+
+
+

Interfacing with Alyx

+

Although this is not mandatory, the IBLRIG GUI is designed to interface with Alyx, the International Brain Laboratory’s database. +This feature allows users to access their subjects and projects directly from the GUI, without the need to manually enter this information.

+

To enable this feature, you must have an Alyx account and have configured your database URL and credentials as mentioned Installation guide.

+
    +
  • The subjects available are the set of alyx subjects that are alive, not stock, and belong to the lab defined in the iblrig_settings.py file.

  • +
  • The projects available are the set of projects of which the current user is a participant. Login to Alyx > Subjects > Projects to check your projects.

  • +
+
+
+

The Command Line Interface

+

To use the command line interface, open a terminal and activate the +environment:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+
+
+
+

Running a single task

+

To run a single task, execute the following command:

+
python .\iblrig_tasks\_iblrig_tasks_trainingChoiceWorld\task.py --subject algernon --user john.doe
+
+
+
+
+

Chaining several tasks together

+

To chain several tasks together, use the --append flag. For +instance, to run a passive task after an ephys task:

+
    +
  1. Run the ephys task

    +
    .\iblrig_tasks\_iblrig_tasks_ephysChoiceWorld\task.py --subject algernon
    +
    +
    +
  2. +
  3. Run the passive task with the --appendflag:

    +
    .\iblrig_tasks\_iblrig_tasks_passiveChoiceWorld\task.py --subject algernon --append
    +
    +
    +
  4. +
+
+
+

Flushing the valve

+

To flush valve 1 of the Bpod, type flush and confirm with ENTER. Press ENTER again to close the valve.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/usage_copy.html b/usage_copy.html new file mode 100644 index 000000000..1049e8bdb --- /dev/null +++ b/usage_copy.html @@ -0,0 +1,284 @@ + + + + + + + Copy commands — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Copy commands

+
+

Usage

+

To initiate the data transfer from the local server to the remote +server, open a terminal and type.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag behavior
+
+
+

The transfer local and remote directories are set in the +iblrig/settings/iblrig_settings.py file.

+

To copy data at another acquisition PC, such as video and ephys, use the relevant tag, e.g.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag video
+
+
+

NB: By default the local data that was copied over 2 weeks ago will be automatically removed. To +avoid this set the cleanup-weeks argument to -1:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data behavior --cleanup-weeks -1
+
+
+

See the ‘Clean-up local data’ section on how to remove data without calling the copy script.

+

To view the copy status of your local sessions without actually copying, use the ‘dry’ argument:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data behavior --dry
+
+
+

For more information on the tranfer_data arguments, use the help flag:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --help
+
+
+
+
+

Clean-up local data

+

To remove sessions fully copied to the server and older than 2 weeks, +open a terminal and type:

+
C:\iblrigv8\venv\scripts\Activate.ps1
+remove-old-sessions
+
+
+

Note: the server needs to be up and running or the sessions won’t be +verified as copied.

+
+
+

Behind the Copy Scripts

+
+

Workflow

+
    +
  1. Initial Stub Creation: At the start of acquisition, an incomplete +experiment description file - a ‘stub’ - is saved to the session +on, both, the local PC and the lab server in a subfolder called +_devices. The filename of the stub includes the PC’s identifier, +allowing the copy script to identify its source.

  2. +
  3. Executing the Copy Script: The copy script is executed on each +acquisition PC independently and in no particular order.

  4. +
  5. Navigating Local Session Data: The script systematically +navigates through local session folders (or optionally a separate +transfers folder) that contain experiment.description stubs.

  6. +
  7. Skipping Transferred Sessions: The script ignores session folders +containing a file named transferred.flag (see 7).

  8. +
  9. Copying Collections: For each session, the script reads the +respective stub and uses rsync to copy each collection. +Subfolders not specified under a collection key are omitted from +copying.

  10. +
  11. Removing Remote Stubs: Upon successful copying, the remote stub +file is merged with the remote experiment.description file (or +copied over if one doesn’t exist already). The remote stub file is +then deleted.

  12. +
  13. Confirming Transfer Locally: A transferred.flag file is +created in the local session folder to confirm the transfer’s +success.

  14. +
  15. Completion and Cleanup: Once no more remote stub files exist +for a given session, the empty _devices subfolder is removed. +Additionally, a ‘raw_session.flag’ file is created in the remote session folder, +indicating the successful transfer of all files.

  16. +
+
+
+

Example of workflow

+

Example of three sessions each in a different copy state:

+
    +
  • The State on the Remote Lab Server

    +
    lab server/
    +└── subject/
    +    └── 2020-01-01/
    +        ├── 001/
    +        │   └── _devices/
    +        │       ├── 2020-01-01_1_subject@taskPC.yaml
    +        │       └── 2020-01-01_1_subject@ephysPC.yaml
    +        ├── 002/
    +        │   ├── _ibl_experiment.description.yaml
    +        │   ├── raw_task_data_00/
    +        │   └── _devices/
    +        │       └── 2020-01-01_1_subject@ephysPC.yaml
    +        └── 003/
    +            ├── raw_task_data_00/
    +            ├── raw_ephys_data/
    +            ├── _ibl_experiment.description.yaml
    +            └── raw_session.flag
    +
    +
    +
  • +
  • The State on the Local Task Acquisition PC

    +
    acquisition computer (taskPC)/
    +└── subject/
    +    └── 2020-01-01/
    +        ├── 001/
    +        │   ├── raw_task_data_00/
    +        │   └── _ibl_experiment.description_taskPC.yaml
    +        ├── 002/
    +        │   ├── raw_task_data_00/
    +        │   ├── _ibl_experiment.description_taskPC.yaml
    +        │   └── transferred.flag
    +        └── 003/
    +            ├── raw_task_data_00/
    +            ├── folder_not_in_desc_file/
    +            ├── _ibl_experiment.description_taskPC.yaml
    +            └── transferred.flag
    +
    +
    +
  • +
  • +
    The State on the Local Ephys Acquisition PC
    acquisition computer (ephysPC)/
    +└── subject/
    +    └── 2020-01-01/
    +        ├── 001/
    +        │   ├── raw_ephys_data/
    +        │   └── _ibl_experiment.description_ephysPC.yaml
    +        ├── 002/
    +        │   ├── raw_ephys_data/
    +        │   ├── _ibl_experiment.description_ephysPC.yaml
    +        └── 003/
    +            ├── raw_ephys_data/
    +            ├── folder_not_in_desc_file/
    +            ├── _ibl_experiment.description_ephysPC.yaml
    +            └── transferred.flag
    +
    +
    +
    +
    +
  • +
+

With the lab server and acquisition pcs in the states above, the +sessions are in the following states

+
    +
  • subject/2020-01-01/001 no data have been copied.

  • +
  • subject/2020-01-01/002 data from taskPC have been copied, data from ephysPC remains to be copied.

  • +
  • subject/2020-01-01/003 data copied from all acquisition PCs.

  • +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/usage_neuropixel.html b/usage_neuropixel.html new file mode 100644 index 000000000..6eff84c42 --- /dev/null +++ b/usage_neuropixel.html @@ -0,0 +1,178 @@ + + + + + + + Neuropixel recording with iblrigv8 — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Neuropixel recording with iblrigv8

+

This document describes how to use the iblrigv8 software to record from the Neuropixel computer.

+
+

Setup

+

Just make sure iblrigv8 is installed according to the instructions and that the iblrig_settings.py +file is configured with the local folder and remote folder for the data transfer.

+

To get access to the viewephys visualizer:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+pip install viewephys
+
+
+
+
+

Starting a task

+

Below shows how to start the electrophysiology for the subject ‘example’ with 2 probes:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+start_ephys_session example 2
+
+
+
+
+

Copy command

+
+

Usage

+

To initiate the data transfer from the local server to the remote server, open a terminal and type.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag ephys
+
+
+

The transfer local and remote directories are set in the +iblrig/settings/iblrig_settings.py file.

+
+
+
+

Look at the raw data

+

This will launch the viewephys GUI, you can then use file -> open and navigate +to open the raw data file you wish to display.

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+viewephys
+
+
+Alternative text +

More information on the viewephys package can be found at: https://github.com/int-brain-lab/viewephys

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/usage_video.html b/usage_video.html new file mode 100644 index 000000000..377dd8ad8 --- /dev/null +++ b/usage_video.html @@ -0,0 +1,197 @@ + + + + + + + Video acquisition computer — iblrig documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Video acquisition computer

+

Video can be run on a separate computer, which is recommended when recording multiple cameras.

+
+

Setup

+
+

Installing drivers

+

Both spinnaker and pyspin must be installed before running an experiment:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+install_spinnaker
+install_pyspin
+
+
+
+
+

Settings config

+

The camera acquisition is configured by parameters in the ‘device_cameras’ key of the hardware_settings.yaml file. +Below is an overview of the parameters:

+
device_cameras:
+  # The name of the configuration. This is passed to the CLI.
+  default:
+    # This is required: the Bonsai workflows to be called by the CLI script.
+    BONSAI_WORKFLOW:
+      # Optional setup (e.g. alignment) workflow
+      setup: devices/camera_setup/EphysRig_SetupCameras.bonsai
+      # Required workflow to be called when the experiment starts
+      recording: devices/camera_recordings/TrainingRig_SaveVideo_TrainingTasks.bonsai
+    # Camera #1 name
+    left:
+      # Required camera device index (assigned in driver software)
+      INDEX: 1
+      # Optional expected frame height. Actual resolution should be set in the driver software.
+      HEIGHT: 1024
+      # Optional expected frame width. This is simply used in QC.
+      WIDTH: 1280
+      # Optional expected frame rate (Hz). This is simply used in QC.
+      FPS: 30
+
+
+

Multiple configurations can be added, e.g. ‘default’, ‘training’, ‘ephys’, etc. and within each, multiple cameras +can be added, e.g. ‘left’, ‘right’, ‘body’, etc. Each configuration requires a BONSAI_WORKFLOW: recording key; +each camera requires an INDEX key.

+
+
+
+

Starting a task

+

Below shows how to start the cameras for the subject ‘example’ with configuration ‘default’:

+
cd C:\iblrigv8\
+venv\scripts\Activate.ps1
+start_video_session example default
+
+
+
+
+

Copy command

+
+

Usage

+

To initiate the data transfer from the local server to the remote server, open a terminal and type.

+
C:\iblrigv8\venv\scripts\Activate.ps1
+transfer_data --tag video
+
+
+

The transfer local and remote directories are set in the +iblrig/settings/iblrig_settings.py file.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2018 – 2024 International Brain Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file