From c44dcf57278201b90ca0c7b6c7aa3044d589a5dd Mon Sep 17 00:00:00 2001 From: retiutut Date: Fri, 28 Jul 2023 21:36:46 +0000 Subject: [PATCH] Deploy website - based on ac36b2cc3e7b23a8bb7e1f6a9ebd57d527823aa8 --- AddOns/AddOnLanding/index.html | 8 ++--- .../Electrodes/ElectrodesLanding/index.html | 8 ++--- AddOns/Headwear/ElectrodeCap/index.html | 8 ++--- .../Headwear/GelfreeElectrodeCap/index.html | 8 ++--- AddOns/Headwear/HeadBand/index.html | 8 ++--- AddOns/Headwear/MarkIV/index.html | 8 ++--- Cyton/CytonDataFormat/index.html | 8 ++--- Cyton/CytonExternal/index.html | 8 ++--- Cyton/CytonLanding/index.html | 8 ++--- Cyton/CytonProgram/index.html | 8 ++--- Cyton/CytonRadios/index.html | 8 ++--- Cyton/CytonSDCard/index.html | 8 ++--- Cyton/CytonSDK/index.html | 8 ++--- Cyton/CytonSpecs/index.html | 8 ++--- Deprecated/8bitBoardDep/index.html | 8 ++--- Deprecated/DeprecatedLanding/index.html | 8 ++--- Deprecated/Hub/index.html | 8 ++--- Deprecated/MarkIII/index.html | 8 ++--- Deprecated/MyoCyton/index.html | 8 ++--- Deprecated/MyoGanglion/index.html | 8 ++--- Deprecated/Python/index.html | 8 ++--- Deprecated/SpiderclawDep/index.html | 8 ++--- Deprecated/UltracortexMark1Dep/index.html | 8 ++--- Deprecated/UltracortexMark2Dep/index.html | 8 ++--- Deprecated/UltracortexMark3Dep/index.html | 8 ++--- .../UltracortexMark3_NovaDep/index.html | 8 ++--- Examples/CommunityPageProjects/index.html | 8 ++--- Examples/EEGProjects/FocusArduino/index.html | 8 ++--- Examples/EEGProjects/MotorImagery/index.html | 8 ++--- .../EMG_Chrome_Dino_Game/index.html | 8 ++--- Examples/EMGProjects/EMG_LED/index.html | 8 ++--- Examples/EMGProjects/EMG_Tetris/index.html | 8 ++--- Examples/EMGProjects/EMGmusic/index.html | 8 ++--- Examples/EMGProjects/EMGpiano/index.html | 8 ++--- Examples/EMGProjects/EMGscrolling/index.html | 8 ++--- Examples/EMGProjects/EMGslideshow/index.html | 8 ++--- Examples/ExamplesLanding/index.html | 8 ++--- Examples/VideoExperiment/index.html | 8 ++--- FAQ/Conduct/index.html | 34 +++++++++++++++++++ FAQ/Cookie/index.html | 10 +++--- FAQ/DocsUpdate/index.html | 8 ++--- FAQ/FAQLanding/index.html | 8 ++--- FAQ/GenFAQ/index.html | 8 ++--- FAQ/HardFAQ/index.html | 8 ++--- FAQ/HowProductsGoTogether/index.html | 8 ++--- FAQ/Liability/index.html | 12 +++---- FAQ/PaymentFAQ/index.html | 8 ++--- FAQ/Privacy/index.html | 10 +++--- FAQ/Returns/index.html | 10 +++--- FAQ/ShippingFAQ/index.html | 8 ++--- ForDevelopers/FirmwareDevelopment/index.html | 8 ++--- ForDevelopers/ForDevelopersLanding/index.html | 8 ++--- ForDevelopers/HardwareDevelopment/index.html | 8 ++--- ForDevelopers/SoftwareDevelopment/index.html | 8 ++--- Ganglion/GanglionDataFormat/index.html | 8 ++--- Ganglion/GanglionLanding/index.html | 8 ++--- Ganglion/GanglionProgram/index.html | 8 ++--- Ganglion/GanglionSDK/index.html | 8 ++--- Ganglion/GanglionSpecs/index.html | 8 ++--- .../Biosensing-Setups/ECGSetup/index.html | 8 ++--- .../Biosensing-Setups/EEGSetup/index.html | 8 ++--- .../Biosensing-Setups/EMGSetup/index.html | 8 ++--- .../Biosensing-Setups/ExGSetup/index.html | 8 ++--- GettingStarted/Boards/CytonGS/index.html | 8 ++--- GettingStarted/Boards/DaisyGS/index.html | 8 ++--- GettingStarted/Boards/GanglionGS/index.html | 8 ++--- GettingStarted/Boards/WiFiGS/index.html | 8 ++--- GettingStarted/Community/Community/index.html | 8 ++--- .../Documentation/DocEdits/index.html | 8 ++--- .../GettingStartedLanding/index.html | 8 ++--- .../BioEra/index.html | 8 ++--- .../BrainBay/index.html | 8 ++--- .../LSL/index.html | 8 ++--- .../Matlab/index.html | 8 ++--- .../Neuromore/index.html | 8 ++--- .../OpenVibe/index.html | 8 ++--- .../VirtualBox/index.html | 8 ++--- Software/OpenBCISoftware/GUIDocs/index.html | 8 ++--- .../OpenBCISoftware/GUIWidgets/index.html | 8 ++--- .../NeuroFly_Toolkit/index.html | 8 ++--- Software/SoftwareLanding/index.html | 8 ++--- ThirdParty/EmotiBit/EmotiBit_Guide/index.html | 8 ++--- ThirdParty/IDUN_Dryode/Dryode/index.html | 8 ++--- ThirdParty/Myoware/MyoWareCyton/index.html | 8 ++--- .../Pulse_Sensor_Landing/index.html | 8 ++--- ThirdParty/ThinkPulse/ThinkPulse/index.html | 8 ++--- ThirdParty/ThirdPartyLanding/index.html | 8 ++--- ThirdParty/WiFiShield/WiFiAPI/index.html | 8 ++--- ThirdParty/WiFiShield/WiFiLanding/index.html | 8 ++--- ThirdParty/WiFiShield/WiFiProgam/index.html | 8 ++--- ThirdParty/WiFiShield/WiFiSDK/index.html | 8 ++--- Troubleshooting/FTDI_Fix_Linux/index.html | 8 ++--- Troubleshooting/FTDI_Fix_Mac/index.html | 8 ++--- Troubleshooting/FTDI_Fix_Windows/index.html | 8 ++--- .../GUI_Troubleshooting/index.html | 8 ++--- .../MacOSGanglionBLEWorkaround/index.html | 8 ++--- .../TroubleshootingLanding/index.html | 8 ++--- Troubleshooting/minimizingNoise/index.html | 8 ++--- assets/js/69fc568b.00343185.js | 1 + assets/js/8ff634cd.8b4400a7.js | 1 - assets/js/8ff634cd.eff73510.js | 1 + assets/js/935f2afb.924ed571.js | 1 + assets/js/935f2afb.edd0b0ec.js | 1 - assets/js/main.51d75156.js | 2 ++ ...CENSE.txt => main.51d75156.js.LICENSE.txt} | 0 assets/js/main.7453b519.js | 2 -- assets/js/runtime~main.5f32cb42.js | 1 + assets/js/runtime~main.c0da0eca.js | 1 - blog/2016/03/11/blog-post/index.html | 8 ++--- blog/archive/index.html | 8 ++--- blog/index.html | 8 ++--- citations/index.html | 8 ++--- help/index.html | 8 ++--- index.html | 8 ++--- search/index.html | 8 ++--- sitemap.xml | 2 +- 116 files changed, 462 insertions(+), 427 deletions(-) create mode 100644 FAQ/Conduct/index.html create mode 100644 assets/js/69fc568b.00343185.js delete mode 100644 assets/js/8ff634cd.8b4400a7.js create mode 100644 assets/js/8ff634cd.eff73510.js create mode 100644 assets/js/935f2afb.924ed571.js delete mode 100644 assets/js/935f2afb.edd0b0ec.js create mode 100644 assets/js/main.51d75156.js rename assets/js/{main.7453b519.js.LICENSE.txt => main.51d75156.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.7453b519.js create mode 100644 assets/js/runtime~main.5f32cb42.js delete mode 100644 assets/js/runtime~main.c0da0eca.js diff --git a/AddOns/AddOnLanding/index.html b/AddOns/AddOnLanding/index.html index c582eb248..95a75184c 100644 --- a/AddOns/AddOnLanding/index.html +++ b/AddOns/AddOnLanding/index.html @@ -12,13 +12,13 @@ Add Ons | OpenBCI Documentation - - + +
Skip to main content

Add Ons

This section summarizes the headwear and electrodes that goes with OpenBCI boards to help gather data.

Headwear

OpenBCI Headwear is designed to make it simple to obtain high-quality EEG Data. The following documents will teach you about them and explain their setup:

  • Ultracortex Mark IV โ€” The newest 8-16 channel 3D Printable Headset, which includes some made-to-order injection-molded parts
  • Headband Kit โ€” The simple, headband kit for up to 8 channels of EEG data.
  • Gel Electrode Cap โ€” silver-silver chlorde, research-grade EEG electrode cap, for gel-electrode based measurement.
  • Gel-free Electrode Cap - Saline-based, research-grade electrode cap with silver-silver chloride electrodes

Electrodes

OpenBCI offers a wide range of electrodes serving various purposes. See the Electrode Guide to learn more about them.

- - + + \ No newline at end of file diff --git a/AddOns/Electrodes/ElectrodesLanding/index.html b/AddOns/Electrodes/ElectrodesLanding/index.html index c15316e9c..b09468ae5 100644 --- a/AddOns/Electrodes/ElectrodesLanding/index.html +++ b/AddOns/Electrodes/ElectrodesLanding/index.html @@ -12,13 +12,13 @@ Electrode Guide | OpenBCI Documentation - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/AddOns/Headwear/ElectrodeCap/index.html b/AddOns/Headwear/ElectrodeCap/index.html index 5be02a77d..937a8e4a0 100644 --- a/AddOns/Headwear/ElectrodeCap/index.html +++ b/AddOns/Headwear/ElectrodeCap/index.html @@ -12,8 +12,8 @@ Electrode Cap Getting Started Guide | OpenBCI Documentation - - + +
@@ -44,7 +44,7 @@ The sintered cap lasts longer and offers more consistent signal due to the unique manufacturing process.
  • I also would like to capture the EOG signal. Can I modify the amplification factor of the biosensing board for each different type of signals? Do you also suggest the best filter specifications for EEG/EOG/EMG recording?

    • By pairing electrodes to the OpenBCI Cytondaisy, you can obtain up to 16 channels from different data sources simultaneously. You can modify the gain on each channel. Please refer to the hardware settings section of the GUI widget guide. Using the gold cup electrodes, ten20 paste, and medical tape, you can capture EOG signals. You would connect both the gold cup electrodes and the electrode cap connections to the CytonDaisy.
  • Can I buy multiple caps (for different head sizes) with this kit?

    • The electrode cap kits come in different sizes. Choose from small, medium, and large in the product page.
  • - - + + \ No newline at end of file diff --git a/AddOns/Headwear/GelfreeElectrodeCap/index.html b/AddOns/Headwear/GelfreeElectrodeCap/index.html index 161e6cfb4..02012f1c2 100644 --- a/AddOns/Headwear/GelfreeElectrodeCap/index.html +++ b/AddOns/Headwear/GelfreeElectrodeCap/index.html @@ -12,8 +12,8 @@ Gelfree Electrode Cap Guide | OpenBCI Documentation - - + +
    @@ -38,7 +38,7 @@ 3) Ensure that everything is dry before storing in a dry place away from sunlight

    Cleaning frequency-after each use.

    Disinfection:

    Disinfection should be carried out only after the cleaning procedure and when it is necessary. Please consider hygienic measures recommended by your local authorities. It is recommended to use very low concentration of disinfectant solution to disinfect the Gelfree BCI cap, electrodes and Hydro-linkTM. Please follow the instructions provided by the manufacturer of the selected disinfectant solution. Please only apply a minimum concentration and a minimum of soaking time required. Make sure that the substances to be disinfected is fully covered with a fairly diluted disinfectant. After disinfection, thoroughly rinse the substances with water and let it dry in air. The recommended disinfectants are as follows: Perfektan TB (Dr. Schumacher GmbH), Envirocide (Metrex), Metricide (Metrex), Cavicide (Metrex), or just diluted household bleach. If you are unable to purchase the products mentioned above brands in your region, a disinfecting product with similar proportions and active ingredients would be recommended.

    Technical Specifications

    MetricValues
    AC Impedance<2.5 kฮฉยทcm2 at 10 Hz
    DC offset voltage<30 mV
    Potential Drift<ยฑ5 mV/10min
    Electrode-scalp impedance< 20 kฮฉ (at 10 Hz)

    Questions, comments, suggestions? Email support@openbci.com

    - - + + \ No newline at end of file diff --git a/AddOns/Headwear/HeadBand/index.html b/AddOns/Headwear/HeadBand/index.html index 4b859d991..d2bca7b4a 100644 --- a/AddOns/Headwear/HeadBand/index.html +++ b/AddOns/Headwear/HeadBand/index.html @@ -12,13 +12,13 @@ OpenBCI EEG Headband Kit Guide | OpenBCI Documentation - - + +
    Skip to main content

    OpenBCI EEG Headband Kit Guide

    Now available in our shop!

    When combined with our Ganglion, Cyton, or CytonDaisy boards, the OpenBCI EEG Headband Kit is a low-cost, easy-to-use device for obtaining research-grade EEG data.

    This tutorial will guide you through setting up your headband kit! Please read this tutorial in its entirety before setting up the system.

    Each kit includes:

    1. Pair of Ear-clip electrodes
    2. Dry comb snap silver-silver chloride coated EEG electrodes
    3. Dry flat snap silver-silver chloride coated EEG electrodes
    4. Pack of snap electrode cables
    5. One adjustable headband strap

    The comb and flat snap electrodes snap in and out of the cables easily. No tools needed.

    All electrode wires end in a female header termination compatible with OpenBCI biosensing boards (Ganglion, Cyton, and CytonDaisy).

    10-20 Internationally Accepted EEG Node Placement

    The flat snap electrodes facilitate multiple frontal cortex measurements (F7, AF7, Fp1, Fpz, Fp2, AF8, F8). The comb snap electrodes will allow measurement at the FT7/FT8, T7/T8, TP7/TP8, P7/P8, PO7/PO8, O1/O2, and Oz nodes, depending where on the adjustable strap you place the electrodes. This kit is intended to provide up to eight channels of EEG data when paired with the Cyton 8-channel board. If you want 16-channels, purchase two headband kits and pair them with the CytonDaisy 16-channel board.

    Headband-Ganglion Tutorial

    The Ganglion board supports four channels of EEG/EMG/EEG input and can stream data over bluetooth or wifi. In this tutorial we will show you how to obtain two frontal lobe measurements and two temporal lobe measurements using the four channels of the Ganglion and stream the data over bluetooth!

    Battery

    All OpenBCI boards ship with a free 2-pin standard JST compatible 4-AA battery holder. For the best user experience, we recommend purchasing the LiPo battery and charger linked below.

    1. Lithium ion battery and
    2. USB charger

    We recommend this battery for its long battery life, compact size, and compatibility with all OpenBCI boards.

    Hardware

    Your Ganglion may have shipped with orange protective cellophane over switches sw1 - sw4. After you've peeled the protective layer off, and flipped the switches to down position, they will look like the image below. Please do not skip this step.

    See the Ganglion Hardware page for a detailed explanation of why we flip the four channel switches to down.

    Steps

    1. Connect one earclip electrode to the top D_G (driven ground) pin, as shown above.
    2. Connect the second earclip electrode to the top REF pin, as shown above.
    3. Connect the female terminations of the two flat snap electrodes and two comb electrodes to top pins 1-4, shown above. (The order of pin connections is up to user preference.)
    4. Place the velcro headband between the snap end of a cable and a snap electrode, making sure to align with the hole in the headband, then press the electrode into place.
    GUI ChannelElectrodeGanglion Board PinElectrode Type
    1Fp1Top +1 pinFlat snap
    2Fp2Top +2 pinFlat snap
    3TP7Top +3 pinComb Snap
    4TP8Top +4 pinComb Snap
    -A1Top D_G pinEar clip
    -A2Top REF pinEar clip

    Assembling the Headband

    The placement of nodes on the headband is best represented in the following image:

    In this diagram, the red circles represent areas where flat electrodes can be placed, and the blue circles represent areas where comb electrodes can be placed. This placement is ultimately up to you, and the areas that you wish to record. However, a general suggestion for standard electrode placement is outlined in yellow.

    To attach the electrodes to the headband:

    1. Place the cable head on the rough side of the velcro
    2. Place the electrode on the soft side of the velcro
    3. Snap the two pieces together, with the velcro in between, to secure them.

    OpenBCI Software

    Now that you've finished with the hardware set-up, the next step is to set up the GUI! Follow the GUI tutorial to prepare your computer to communicate with your Ganglion.

    Once you've downloaded the GUI zip file per tutorial instructions, fire up the GUI as shown in this YouTube video!

    Notice the sharp peak-trough-peak wave behavior in the upper left time series window of the GUI. The first peak corresponds with the initiation of an eye blink, the trough immediately after shows a dip in alpha brain waves that syncs to the eye's closing for a fraction of a second! The peak immediately after the trough corresponds to the brain signals to the eyelid to reopen, thus concluding the blink cycle.

    The band power window in the lower right of the GUI shows the relative strengths of the user's alpha, beta, gamma, delta, and theta brain waves. The GUI and Ganglion work together to separate and categorize brain waves based on characteristics like frequency and amplitude.

    In the picture above, you can see the Ganglion Signal window in the lower left of the GUI. This widget helps users establish a quality connection for each electrode. For most bioelectrical measurements, you want the skin-electrode contact surface impedance to be low. Two of the four channels show lower impedance (these happen to be the flat snap electrodes that are touching the skin over the frontal cortex). This connection must be good, hence the green light to the left of the impedance value. If the impedance light in the GUI is red, you can improve the connection by making sure the electrodes are secured against the skin and making good contact. You may find it helpful to add a little electrode paste to boost conductivity of the Ag-AgCl coating on the electrodes.

    Another widget shown in the picture above is the Focus widget. When the alpha waves are (relatively) high and beta waves are low, the GUI translates this to a focused state. Download the latest GUI 5.x.x with updated Focus Widget.

    Headband-Cyton Tutorial

    The Cyton board supports eight channels of EEG/EMG/EEG input and can stream data over bluetooth or wifi. In this tutorial we will show you how to obtain three frontal lobe measurements and five temporal lobe measurements and stream the data over bluetooth!

    Battery

    All OpenBCI boards ship with a free 2-pin standard JST compatible 4-AA battery holder. For the best user experience, we recommend purchasing the LiPo battery and charger linked below.

    1. Lithium ion battery and
    2. USB charger

    Hardware

    As shown above:

    1. Connect one earclip electrode to the bottom BIAS pin
    2. Connect the second earclip electrode to the bottom SRB pin
    3. Connect the female terminations of the three flat snap electrodes to bottom pins 1-3 (labeled N1P, N2P, and N3P). (The order of pin connections is up to user preference.)
    4. Connect the female terminations of up to five comb electrodes to bottom pins 4-8 (labeled N4P through N8P). (The order of pin connections is up to user preference.)
    5. Place the velcro headband between the snap end of a cable and a snap electrode, making sure to align with the hole in the headband, then press the electrode into place.
    GUI ChannelElectrodeCyton Board PinElectrode Type
    1Fp1Bottom N1P pinFlat snap
    2Fp2Bottom N2P pinFlat snap
    3FpzBottom N3P pinFlat snap
    4TP7Bottom N4P pinComb Snap
    5TP8Bottom N5P pinComb Snap
    6P7Bottom N6P pinComb Snap
    7P8Bottom N7P pinComb Snap
    8OzBottom N8P pinComb Snap
    -A1Bottom SRB pinEar clip
    -A2Bottom BIAS pinEar clip

    Assembling the Headband

    The placement of nodes on the headband is best represented in the following image:

    In this diagram, the red circles represent areas where flat electrodes can be placed, and the blue circles represent areas where comb electrodes can be placed. This placement is ultimately up to you, and the areas that you wish to record. However, a general suggestion for standard electrode placement is outlined in yellow.

    To attach the electrodes to the headband:

    1. Place the cable head on the rough side of the velcro
    2. Place the electrode on the soft side of the velcro
    3. Snap the two pieces together, with the velcro in between, to secure them.

    OpenBCI Software

    Now that you've finished with the hardware set-up, the next step is to set up the GUI! Follow the GUI tutorial to prepare your computer to communicate with your Cyton.

    Once you've installed the GUI by following the tutorial, fire it up as shown in this YouTube video!

    Play around with the vertical scale, filter, frequency range to see the effect on the raw data. The following screenshot shows an example of what your live-streamed brain data might look like.

    For more details on the various GUI functions, scroll up to the OpenBCI Software section of the Headband-Ganglion Tutorial above.

    For cool project ideas, head over to the Example Projects Directory!

    Use Cases for OpenBCI GUI

    • OpenBCI device owners want to visualize their brainwaves!
    • Many of the researchers, hackers and students alike who purchase OpenBCI devices want to use them to acquire data as soon as their device arrives.
    • Users use macOS, Windows and Linux to acquire data
    • Users want to filter incoming data in real time
    • Users want to make their own experiments to test their awesome theories or duplicate state of the art research at home!
    • Users struggle to get prerequisites properly installed to get data on their own from OpenBCI Cyton and Ganglion.
    • Users want to stream data into their own custom applications such as MATLAB.

    What You Can Do with OpenBCI GUI and Software Stack

    • Visualize data from every OpenBCI device: Ganglion, Cyton, Cyton with Daisy, and the WiFi Shield
    • Playback files using GUI
    • Run as a native application on macOS, Windows, and Linux.
    • Apply filters and other data processing tools to quickly clean raw data in real time
    • Use the GUI as a networking system to move data out of GUI into other apps over UDP, OSC, LSL, and Serial.
    • Send data to MATLAB, Neuropype (using LSL), and other third-party softwares.
    • Analyze data with Python and Brainflow
    • Create a widget framework that allows users to create their own experiments.
    • Output data into a saved file for later offline processing.
    • Customize the layout, change the gain, toggle on/off, check impedance of individual channels of the CytonDaisy board (or any connected OpenBCI board) directly in the GUI!
    • Access built-in widgets such as Focus Widget, Band Power, Accelerometer, EEG Head Plot, and MUCH more

    As always, don't hesitate to email us at support@openbci.com for assistance!

    Headband Tips and Signal Troubleshooting

    • Moisten a Q-Tip in rubbing alcohol, and scrub the surface of the head directly underneath the contact point for each electrode. This will remove oil/debris from the skin, resulting in a better signal. Then place the headband on the head, with the center electrode in the center of the forehead.
    • Optional - The flat and snap electrodes can be used with electrode gel. Inject electrode gel into the contact area using any standard small syringe. This will improve signal quality by lowering the skin-electrode impedance.
    • We recommend using a thin, flat tool to remove the flat snap electrodes. Un-snap it with the help of a thin screwdriver.
    - - + + \ No newline at end of file diff --git a/AddOns/Headwear/MarkIV/index.html b/AddOns/Headwear/MarkIV/index.html index 6f3f2143e..c900f4bb1 100644 --- a/AddOns/Headwear/MarkIV/index.html +++ b/AddOns/Headwear/MarkIV/index.html @@ -12,8 +12,8 @@ Ultracortex Mark IV | OpenBCI Documentation - - + +
    @@ -28,7 +28,7 @@ image image image

    Adjust the Ultracortex for your head

    Put the Ultracortex Mark IV onto your head and gradually tighten the electrode units until the electrodes are snugly (but comfortably) against your scalp. Tighten the electrodes and comfort units by turning them clockwise, and loosen them by turning counterclockwise.

    Be careful not to strain the electrode wires when twisting the electrode units, or you may separate the wire from the electrode itself. You must disconnect a blue electrode mount from its colored wire before turning it.

    Examine your brain waves!

    Place your UltraCortex on your head so that the back center node is roughly the same distance above your inion (bump on the back of your skull) as the front center node is above the bridge of your nose. As you place the UltraCortex on your head, the springs should adjust to the shape and size of your head.

    Now that you have your Ultracortex assembled and comfortably adjusted to your head size and shape, it's brain wave time!

    image

    Check out the Getting Started w/ OpenBCI tutorial to get up-and-running with the OpenBCI GUI.

    Below is a screenshot of what the GUI looks like when you've got your OpenBCI Cyton + Ultracortex (w/ 8 channels) hooked up! You can see a nice alpha (~10 hz) spike on the FFT Plot.

    image

    The OpenBCI GUI has a widget for visualizing signal strength at each electrode. To view it, click on the "FFT Plot" drop-down menu in the top right corner. Select "Head Plot".

    You should now see a visual map of signal strength in the top right corner.

    image

    Give Us Feedback!

    If you have questions, comments, or suggestions regarding the printing and/or assembly of the Ultracortex, we'd love to hear from you. Please submit issues to this repository or email us at contact@openbci.com. Or take some pictures of yourself wearing the Ultracortex and Tweet at us (@OpenBCI & @Ultracortex)!

    - - + + \ No newline at end of file diff --git a/Cyton/CytonDataFormat/index.html b/Cyton/CytonDataFormat/index.html index 5fd150862..5df1c285f 100644 --- a/Cyton/CytonDataFormat/index.html +++ b/Cyton/CytonDataFormat/index.html @@ -12,8 +12,8 @@ Cyton Data Format | OpenBCI Documentation - - + +
    @@ -23,7 +23,7 @@ AZ1-AZ0: Data value for accelerometer channel Z

    Firmware Version 2.0.0 (Fall 2016 to Now)

    The following table is sorted by Stop Byte. Drivers should use the Stop Byte to determine how to parse the 6 AUX bytes.

    Stop ByteByte 27Byte 28Byte 29Byte 30Byte 31Byte 32Name
    0xC0AX1AX0AY1AY0AZ1AZ0Standard with accel
    0xC1UDFUDFUDFUDFUDFUDFStandard with raw aux
    0xC2UDFUDFUDFUDFUDFUDFUser defined
    0xC3ACAVT3T2T1T0Time stamped set with accel
    0xC4ACAVT3T2T1T0Time stamped with accel
    0xC5UDFUDFT3T2T1T0Time stamped set with raw aux
    0xC6UDFUDFT3T2T1T0Time stamped with raw aux

    AX1-AX0: Data value for accelerometer channel X AY1-AY0: Data value for accelerometer channel Y AZ1-AZ0: Data value for accelerometer channel Z

    We can still fit a 25Hz accelerometer in with time stamps due to some interlacing and timing constraints. Since we stream channel data at 250Hz and accelerometer at 25Hz; we have essentially 10 samples to send the accelerometer data in. When a 0xC3 or 0xC4 you should parse Byte 27 to indicate what Byte 28 is:

    Byte 27Byte 28
    'X'AX1
    'x'AX0
    'Y'AY1
    'y'AY0
    'Z'AZ1
    'z'AZ0

    Where AC stands for accel code and is an ASCII character. An upper case signifies that Byte 28 is the upper 8 bits of the 16 bit signed integer, while a lower case character represents the lower 8 bits of the 16 bit signed integer. You combine both bytes to form the one number. For example, let's say a sample comes in with AC equal to 'X', we would then store the value in AV to a temporary variable. The next sample comes in with 'x' for it's AC byte, we would then combine this sample's Byte 28 with the previous sample's Byte 28 and then convert as described in the section below called 16-Bit Signed Data Values.

    T3-T0: 32 bit unsigned integer OpenBCI board time representing time since the board was started in ms. Simply store as an unsigned integer.

    0xC3 and 0xC5 are special in that they contain the same exact data as their counter parts 0xC4 and 0xC5. However 0xC3 and 0xC5 are only sent after the time stamp/sync (<) command is issued from the PC/Driver to the Board. When the Board parses a < it sets a flag high to send on the next sample a different end byte to allow for the PC/Driver to calculate a round trip response time.

    UDF stands for User Defined and for a general driver perspective, should be left alone and sent up to the user.

    24-Bit Signed Data Values

    For the EEG data values, you will note that we are transferring the data as a 24-bit signed integer, which is a bit unusual. We are using this number format because it is the native format used by the ADS1299 chip that is at the core of the Cyton board. To convert this unusual number format into a more standard 32-bit signed integer, you can steal some ideas from the example Processing (aka, Java) code:


    int interpret24bitAsInt32(byte[] byteArray) {
    int newInt = (
    ((0xFF & byteArray[0]) <! 16) |
    ((0xFF & byteArray[1]) <! 8) |
    (0xFF & byteArray[2])
    );
    if ((newInt & 0x00800000) > 0) {
    newInt |= 0xFF000000;
    } else {
    newInt &= 0x00FFFFFF;
    }
    return newInt;
    }

    16-Bit Signed Data Values

    The accelerometer data, if used, is sent as a 16bit signed value. We're using a similar scheme to convert these values into 32bit integers in Processing.


    int interpret16bitAsInt32(byte[] byteArray) {
    int newInt = (
    ((0xFF & byteArray[0]) <! 8) |
    (0xFF & byteArray[1])
    );
    if ((newInt & 0x00008000) > 0) {
    newInt |= 0xFFFF0000;
    } else {
    newInt &= 0x0000FFFF;
    }
    return newInt;

    {"}"}

    32-Bit Unsigned Time Stamp

    To time stamp data, if used, is sent as a 32 bit unsigned integer representing time since the board was started in ms. We are using a different scheme to convert these values into 32 bit integers in Processing.

    Interpreting the EEG Data

    Once you receive and parse the data packets, it is important to know how to interpret the data so that the EEG values are useful in a quantitative way. The two critical pieces of information are (1) the sample rate and (2) the scale factor.

    For the sample rate, we set the default rate to 250 Hz. Faster rates are supported by the ADS1299, but the RFDuino wireless link and the serial limits might not be able to keep up with faster sample rates. If you give it a try, let us know how it worked!

    For the scale factor, this is the multiplier that you use to convert the EEG values from โ€œcountsโ€ (the int32 number that you parse from the binary stream) into scientific units like โ€œvoltsโ€. By default, our Arduino sketch running on the OpenBCI board sets the ADS1299 chip to its maximum gain (24x), which results in a scale factor of 0.02235 microVolts per count. Because the gain is user-configurable (24x, 12x, 8x, 6x, 4x, 2x, 1x), the scale factor will be different. If the gain is changed, the equation that you should use for determining the scale factor is:


    Scale Factor (Volts/count) = 4.5 Volts / gain / (2^23 - 1);

    Note that 2^23 might be an unexpected term in this equation considering that the ADS1299 is a 24-bit device. That's because the 24bit raw count value is in 2's complement format. This equation is from the ADS1299 data sheet, specifically it is from the text surrounding Table 7. This scale factor has also been confirmed experimentally using known calibration signals.

    Accelerometer data must also be scaled before it can be correctly interpreted. The equation used to scale Accelerometer data is as follows (We assume 4Gs, so 2mG per digit):


    Accelerometer Scale Factor = 0.002 / 2^4;

    As of January 2021, these constants and equations are included in BrainFlow for Cyton users! This means users can pick any supported language and the data will already be scaled appropriately. These equations are still necessary if you plan to use data stored to SD card using a Cyton.

    16 Channel Data with Daisy Mdule

    Our 16 channel system allows for control of individual settings for all 16 channels, and data is retrieved from both ADS1299 IC at a rate of 250SPS. The current bandwith limitations on our serial radio links limit the number of packets we can send. To solve for this, we are sending data packet at the same rate of 250SPS, and alternating sample packets between the on Board ADS1299 and the on Daisy ADS1299. The method takes an average of the current and most recent channel values before sending to the radio. The first sample sent will be invalid because there is no previous sample to average it with. After this, on odd sample numbers, the Board ADS1299 values are sent, and on even sample numbers, the Daisy ADS1299 samples are sent. When running the system with 16 channels, it is highly recommended that you use an SD card to store the raw (un-averaged) data for post processing.

    sample#recordedsentsent
    0board(0),daisy(0)an invalid sample
    1board(1),daisy(1)avg(board(0),board(1))
    2board(2),daisy(2)avg(daisy(1),daisy(2))
    3board(3),daisy(3)avg(board(2),board(3))
    4board(4),daisy(4)avg(daisy(3),daisy(4))
    5board(5),daisy(5)avg(board(4),board(5))
    6board(6),daisy(6)avg(daisy(5),daisy(6))

    The received averages might be upsampled to 250SPS in the following simple manner:

    receivedupsampled board dataupsampled daisy data
    sample(3)avg(sample(1),sample(3)sample(2)
    sample(4)sample(3)avg(sample(2),sample(4)
    sample(5)avg(sample(3),sample(5)sample(4)
    sample(6)sample(5)avg(sample(4),sample(6)
    sample(7)avg(sample(5),sample(7)sample(6)
    sample(8)sample(7)avg(sample(6),sample(8)

    The times of the upsampled values are delayed by 1 sample compared to the received values.

    Room For Improvement

    Change protocol to meet other standards. The over-air data is sent in packets (or frames, depending upon your preferred word). The maximum bytes allowed per packet is 32. We are reserving the first byte to use as a packet check-sum in our protocol. So the available bytes-per-packet, as far as the uC is concerned, is 31. The over-air protocol that the Dongle/RFduino Host gets is:

    Our Host code removes the Packet Counter and adds the header and footer. It could be modified to work natively with other protocol specs for other signal processing software....

    Data Compression. In situations where an increase in the sample rate, or higher channel counts are desired, a data compression scheme can be implemented. As noted above, when sending only the ADS1299 values for 8 channels there are six unused bytes in the radio packet. It may be possible to, for example, increase the sample rate, and compress two samples worth of ADS data into a single radio packet. Or fit all 16 channels of data into a single packet and avoid the averaging that is currently used.

    - - + + \ No newline at end of file diff --git a/Cyton/CytonExternal/index.html b/Cyton/CytonExternal/index.html index 4e1b1a2b3..3b7128da4 100644 --- a/Cyton/CytonExternal/index.html +++ b/Cyton/CytonExternal/index.html @@ -12,8 +12,8 @@ External Trigger on OpenBCI Cyton Board | OpenBCI Documentation - - + +
    @@ -30,7 +30,7 @@ OBCI.useAux = true; // option to add/remove auxiliary data to stream // more stuff... {"}"}


    void loop(){
    // do stuff
    triggerValue = digitalRead(triggerPin); // feel the trigger pin
    if (triggerValue != lastTriggerValue){ // if it's changed,
    if (triggerValue == LOW){ // if it's gone from HIGH to LOW
    // 0x6220 converts to PI in GUI
    OBCI.auxData[0] = OBCI.auxData[1] = OBCI.auxData[2] = 0x6220;
    addAuxToSD = true; // add Aux Data to the SD card if it's there
    state = !state; // toggle the state variable
    digitalWrite(LED,state); // toggle the LED for user useability
    }
    lastTriggerValue = triggerValue; // keep track of the changes
    }

    // do other stuff
    }

    Have fun, be safe, and, as always, we're here to help

    - - + + \ No newline at end of file diff --git a/Cyton/CytonLanding/index.html b/Cyton/CytonLanding/index.html index 3c1f298f2..3a5c81213 100644 --- a/Cyton/CytonLanding/index.html +++ b/Cyton/CytonLanding/index.html @@ -12,13 +12,13 @@ Cyton Board | OpenBCI Documentation - - + +
    Skip to main content

    Cyton Board

    Buy it!

    This set of tutorials will show you everything you need to know about the OpenBCI 8-channel Cyton Biosensing Board.

    Cyton

    Included will be:

    • Spec Overview โ€” The specs of the board and dongle, including explanations of the components and circuit schematics.
    • OpenBCI Daisy Module โ€” The specs of the Daisy daughter card to the Cyton, which expands the number of sensor channels.
    • Data Sheet โ€” A rundown of the defined data format for the Cyton.
    • OpenBCI Cyton SDK โ€” Goes over the byte string command protocol that is compatible for use with the OpenBCI Cyton Board.
    • OpenBCI Board Programming Tutorial โ€” Tutorial explaining how to reprogram the OpenBCI Cyton Board using the OpenBCI Dongle and your PC, allowing you to update firmware or hope to customize the board. Not needed if you wish to use the board out-of-box
    • OpenBCI Radio Programming Tutorial โ€” Learn how to manually program the Radios on the Cyton and Dongle. Not needed if you wish to use the board out-of-box
    • External Trigger on OpenBCI Cyton Board โ€” Shows how to add an external trigger to the OpenBCI data stream to allow for precise timing between external events and the data stream.
    • Using SD Card with OpenBCI โ€” Covers how to add an SD card for local storage to OpenBCI.
    - - + + \ No newline at end of file diff --git a/Cyton/CytonProgram/index.html b/Cyton/CytonProgram/index.html index f7f3c7ae9..22a318e44 100644 --- a/Cyton/CytonProgram/index.html +++ b/Cyton/CytonProgram/index.html @@ -12,8 +12,8 @@ Cyton Board Programming Tutorial | OpenBCI Documentation - - + +
    @@ -24,7 +24,7 @@ Program flash: ...................................#################################### done appears, 99 out of 100 times your firmware uploaded correctly. If your board doesn't appear to be working in the GUI (or other software), simply try re-uploading the firmware.

    Upload32

    8bit Upload How-To

    NOTE: The 8bit Hardware is no longer in production

    You will need:

    OpenBCI Dongle

    Make sure that the slide switch on the OpenBCI Dongle is switched to the GPIO6 selection. That way the DTR reset signal will get passed over-air to the ATmega328. If it's on the other side, it will try to program the Dongle-mounted RFduino!
    You can find the latest firmware and libraries on our github repository

    You will need to install these files from our repository into your Documents/arduino/libraries folder

    ArduinoIDE

    Move the file OpenBCI_8bit_SD.ino into your Documents/arduino folder, and start up the Arduino IDE. you should then see the sketch in your Sketch folder.

    selectBoardUno

    Select Arduino UNO from the Board drop-down menu.

    selectSerialPort

    Select the correct serial port for your OpenBCI Dongle.

    Upload

    When you are happy with the code, simply press upload to program the OpenBCI 8bit target. That's it! You will see some blinky lights on the Dongle, and after a short while, the Arduino IDE will tell you that it's done.

    Troubleshooting

    If you're having an issue with Board_Defs.h and you're uploading using Linux, you must move ALL files located in: /Arduino/hardware/chipkit-core/pic32/variants/openbci/ to /Arduino/hardware/chipkit-core/pic32/cores/pic32/ This should fix any issues you're having compiling.

    If the upload fails with No Target Found:

    1. Unplug the Dongle and Device.
    2. Plug the Dongle into your computer.
    3. Plug the Device into your computer.
    4. Put the device into bootloader mode.
    5. Try upload again.

    If the upload fails with Program Flash Failed it's due to the Arduino IDE not being able to read from the serial port fast enough possibly do to resource starvation or overall computer power. We recommend taking the following actions:

    In extreme conditions, if you have tried all five of the above methods and still can't upload, then you can try to change the Device's polling time. The Poll Time can be adjusted using the OpenBCI Radio Config Utility software.

    Notes On Updating and Using v2.0.0 Cyton Firmware

    Overview

    The OpenBCI Cyton boards were updated with new firmware across all three main microcontrollers, the Pic 32 (Pic32) and both RFduinos on the Dongle (Host) and the Board (Device). This tutorial does not explain how to program the firmware using the OpenBCI Dongle and PC; you will want to refer to the tutorials Cyton Board Programming Tutorial and Cyton Radios Programming Tutorial. If you have spent a lot of time writing custom Arduino code to run on the OpenBCI, then you will find this tutorial helpful in upgrading to get the new stability and features of the 2.0.0 firmware.

    Sending data packets from the Pic32 to the PC

    At 250Hz, we are at the upper limit of the physical hardware. The Device RFduino must send data packets as soon as it gets them from the Pic32 because of the slow serial baud rate between Pic32 and Device (115200 baud, a faster baud rate messes up the radio on the Device). On the other hand, over the air programming must be able to combine multiple radio packets together into one page and write at one time, therefore, over the air programming must wait to see if it received all data over the serial port before sending. These two requirements led to the original firmware being stateful, where the Device and Host would be in either streaming or not streaming mode. This led to problems and could result in the PC not being able to contact the Cyton because the radios were stuck in streaming mode and the reset button on the Cyton is not tied to the Device so one would have to power cycle the entire Cyton.

    An Example

    Let's say you want to send custom data from the Cyton to the PC. In order to do that simply wrap the data with the correct start byte, 0x41, and stop byte, 0xCX (where X is 0-F in hex). In the OpenBCI_32bit_Library code base:


    /*
    * @description Writes channel data and axisData array to serial port in
    * the correct stream packet format.
    *
    * Adds stop byte OPENBCI_EOP_STND_ACCEL. See OpenBCI_32bit_Library_Definitions.h
    */
    void OpenBCI_32bit_Library::sendChannelDataWithAccel(void) {

    Serial0.write('A'); // 0x41 1 byte

    Serial0.write(sampleCounter); // 1 byte

    ADS_writeChannelData(); // 24 bytes

    accelWriteAxisData(); // 6 bytes

    Serial0.write(OPENBCI_EOP_STND_ACCEL); // 0xC0 1 byte

    sampleCounter++;

    }

    This code writes 33 bytes of data from the Pic32 to the Device in the correct format and therefore as soon as it arrives at the Device it will be sent to the Host and to the PC. New to firmware version 2 is the ability to have different stop bytes, in the original firmware, one could only send stop bytes of 0xC0 however now, we can send 0xCn where n is 0-F (hex).
    Important if you want to only send 20 bytes of data per packet, you still must send this 33 bytes with the proper start and stop bytes. Sending data too fast will result in a buffer overflow on the Device and cause the system to restart and send an error message to the Host and PC.

    Sending one byte of data every 10ms or 100Hz

    Here is an example taken from the file called BoardWithCustomData.ino from the examples folder in the OpenBCI_32bit_Library repo.


    void sendLEDStatus() {
    // Must have header byte
    Serial0.write('A'); // 0x41 1 byte
    // Write the LED state
    Serial0.write(LEDState); // 1 byte
    // Fill the rest with fake data
    for (int i = 0; i < 30; i++) {
    Serial0.write(0x00);
    }
    // Send a stop byte with an `B` or `1011` in the last nibble to indicate a
    // different packet type.
    Serial0.write(0xCB); // 1 byte
    }

    As you can see above, we only really want to send 1 byte, but if we want to do it fast, at this 100Hz rate, we must wrap it in the start byte and stop byte to tell the Device to send the packet as soon as it get's the stop byte.

    Adopting the new Pic32 code paradigm

    We drastically reduced the complexity of the .ino files in order to make custom device programming more approachable for new programmers but also add a suite of features to give great power to great programmers. We have created an environment to drive contribution to the main project in the form of examples. If you want to contribute code the main library for others to use, now you can simply do a pull request. Joel was able to adapt his pulse sensor code to the new firmware in about 20 minutes! Now anyone who downloads the firmware, will get the pulse sensor code versus having to dig through all the OpenBCI repos to find an example of how to use a pulse sensor, have external triggers, read an analog input, etc...

    Please dig through the examples folder on the OpenBCI_32bit_Library for a deep dive into all the possibilities with the new code. Remember if you have new code you want to share, please do!! Make a pull request!

    - - + + \ No newline at end of file diff --git a/Cyton/CytonRadios/index.html b/Cyton/CytonRadios/index.html index 7ff309413..a53a251f8 100644 --- a/Cyton/CytonRadios/index.html +++ b/Cyton/CytonRadios/index.html @@ -12,8 +12,8 @@ Cyton Radios Programming Tutorial | OpenBCI Documentation - - + +
    @@ -26,7 +26,7 @@ FTDI Friend Back

    Another example would be the FTDI Friend from Adafruit. In this case, the pin labled 'RTS' is the one you want to connect to the RF RST on the OpenBCI board. We need to ensure that the 'RTS' pin is behaving correctly and that we're sending 3V logic out! Note the image of the back of the FTDI Friend. I have jumped the pads marked DTR, and also the 3V pads on VCC out. The Signal Logic Level already has the 3V pads jumped. I cut the trace on the RTS and 5V pads as well. These are the correct settings for uploading to RFduino using FTDI Friend. The 'RTS' pin jump to OpenBCI RF RST connection will also need a 0.1uF series capacitor. These breakouts are awesome, but they can be alittle advanced.

    FTDI Basic Breakout

    FTDI BasicFront FTDI BasicBack

    Sparkfun makes an FTDI breakout as well, and they come in a couple of flavors. 5V and 3V. By now, you know that you want the 3V Version. [pic coming soon] The Basic Breakout isn't as fancy as the FTDI Friend, but you do need to put a 0.1uF capacitor between the DTR pin and the RF RST pin. Also, if you have a version of this board with a voltage selection on the back, make sure that it has the 3.3V pads connected and the 5V pads cut!

    Uploading Host Firmware to the OpenBCI Dongle

    Overview

    DongleBack

    This process does not require 3rd party hardware. Before you begin, note that there is a switch on the dongle that allows for selection between RESET and GPIO6. This switch routes the DTR pin from the FTDI chip to either RESET or GPIO6 pin on the RFduino module. When the switch is in the GPIO6 position, the Dongle is ready for general communication, code upload, and streamingData mode to the OpenBCI Board. When the switch is in the RESET position, it is possible to upload code to the RFduino right there on the Dongle.

    Upload HOST Firmware Version 2.x.x (Fall 2016)

    Steps:

    1. In the Arduino IDE 1.5.8 go File-->Examples-->OpenBCI_Radios-->RadioHost32bit which will launch the Host firmware.

    2. Then go to Tools-->Board and select RFduino.

    3. Plug the Dongle into your computer. Flip the switch to the Reset position if it is not already.

    4. Now go Tools-->Port and select the COM port (Windows) or /dev/tty.usbserial-* port (Mac/Linux) for your device or

    5. Click "Verify" on the toolbar (checkmark icon) to verify everything is ready. If you see Done Compiling then you are ready to go!

    6. Choose a channel number for your device. The channel number can be set in the code see radio.begin(OPENBCI_MODE_HOST,20);.

    7. Click "Upload" on the toolbar (the icon to the right of the checkmark). Your code is now uploading to the OpenBCI Dongle!

    Important! As of firmware version 2, you must first flash the board with the line radio.flashNonVolatileMemory(); in the setup() function uncommented, then comment the line back out and program again. It is very important that you reprogram the board with the line commented out. We must do this because with firmware version two, the channel number is stored to non-volatile memory so we can change the channel number of the system from the PC/Driver, turn the system off and still remember the newly set channel. If this is your first time uploading firmware version two (your bought your board prior to October 2016), you may ignore this message the first time you upload radio code.

    Using Radio Firmware Version 1.x.x (2014 - Fall 2016)

    The following is for working with our original radio firmware. Please refer to the images above when following these instrucitons.

    Getting Radio Firmware Version 1.x.x (2014 - Fall 2016)

    Download the OpenBCI_Radios repo from our github, and place it in the proper location depending upon your OS.

    Put the RFduino folder and everything it contains in one of the following folders:


    On Mac: /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino

    On Windows: C\Program Files (x86)\Arduino-1.5.x\hardware\arduino

    Note: To upload code to the Cyton board, you need Arduino v1.8.0 or later, while you need Arduino v1.5.8 to upload code to the dongle. If you have already installed Ardiono v1.8.0, you may see an error message while installing 1.5.8 saying that you need to uninstall v1.8.0. Instead of doing that, simply move the existing "Arduino" program folder (which should be 1.8.0) in your Program Files to another folder (such as "Documents"). Go to your program manager (called "Change or Remove Program" in Windows, press Uninstall Arduino 1.8.0, and confirm if told that there was an error in uninstalling 1.8.0. Then, install 1.5.8. Rename the new "Arduino" program folder (which should now be 1.5.8) to "Arduino 1.5.8", and rename the Arduino folder that you moved to the name "Arduino 1.8.0". Move this folder back to your Program Files where "Arduino 1.5.8" is located, allowing you to keep both versions.

    Note for Windows users While installing 1.5.8 if the installer instructs you to uninstall 1.8.0, move the Arduino folder from Program Files (x86) to your downloads folder. Rename this folder to Arduino_1.8.0. Open the Change or remove program app in control panel and uninstall the Arduino application. There will be a popup indicating that the files do not exist and asking if you want to remove the program from the files list, select yes. Then install 1.5.8 as normal. Navigate to back to your Program Files (x86) folder and locate the Arduino folder. Rename this folder to Arduino_1.5.8. Now drag and drop the Arduino_1.8.0 back into Program Files (x86) folder.

    The files contained in the RFduino folder are custom builds for OpenBCI by our good friends over at RFdigital. Those guys are great! They helped us to squeeze all of the speed we could get out of the RFduinoGZLL library, and also gave us access to 25 discreet channels for OpenBCI boards to work on. ROCK!

    Upload DEVICE Radio Firmware Version 1.x.x (2014 - Fall 2016)

    For 32bit boards, you will want to upload: OpenBCI_32bit_Device.ino

    For 8bit boards, you will want to upload: OpenBCI_8bit_Device.ino

    Upload Pass Thru Radio Firmware Version 1.x.x (2014 - Fall 2016)

    We provide an Arduino sketch called OpenBCI_Dongle_PassThru.ino which makes this possible. After uploading, make sure to move the switch back over to the GPIO6 side!

    Now hit the upload button, it's the button to the right of the check mark in the top left of the IDE. Don't worry! You can re-load the Host code easily after programming the Device. After uploading, make sure to move the switch back over to the GPIO6 side!

    Upload HOST Firmware Version 1.x.x (2014 - Fall 2016)

    If you want to modify the firmware that the OpenBCI Dongle came with, or roll your own, make sure that you are setting the RFduino up as a HOST, and that channel is selected correctly. The channel your boards were shipped with is noted on the anit-static baggie that it came in.


    // place this above the setup()
    #include <RFduinoGZLL.h> // using the Gazelle Stack
    device_t role = HOST; // This is the HOST

    void setup(){
    RFduinoGZLL.channel = 6; // use channels 2-25. 1 is same as 0 and 0-8 in normal GZLL library
    RFduinoGZLL.begin(role); // start the GZLL stack
    // more stuff here
    }

    Also, make sure that you use the code that is specific to your board. There are important differences between the way the 8bit and Cyton code functions! Both the 8bit Host and Cyton Host code are downloaded with the RFduino libraries above.

    - - + + \ No newline at end of file diff --git a/Cyton/CytonSDCard/index.html b/Cyton/CytonSDCard/index.html index 44c138e44..fb01350b7 100644 --- a/Cyton/CytonSDCard/index.html +++ b/Cyton/CytonSDCard/index.html @@ -12,8 +12,8 @@ Using SD Card with Cyton and CytonDaisy Board | OpenBCI Documentation - - + +
    @@ -22,7 +22,7 @@ SecureErase ScanDiskFormatterMAC

    Formatting SD Card on Windows

    ScanDiskFormatterWin ScanDiskFormatterOverwriteWIN

    Another, and some say better, option is to use the SD Association's own formatter software. Download it here. (available for Windows and Mac). We recommend using it if you are on a Windows machine, because the Windows format option does not allow for overwriting the disk. Make sure to select OverWrite Format Type when using the SDFormatter tool on Windows or Mac.

    Formatting SD Card on Linux

    If you are using Linux, you can simply search the internet for "How to Format SD Card on Linux" and pick your favorite method.

    Block Writing

    In order to write OpenBCI data to the SD card in a timely fashion, we are using a block writing technique in Arduino and chipKIT. Blocks are 512 bytes. That means that OpenBCI will collect bytes as they come in from the sensors, and when a block is complete (512 bytes) it is written to the file on SD card. First, of course, the file needs to be created, and memory on the card allocated. OpenBCI uses ASCII commands to control the creation of a file. The following key commands allocate different amounts of SD card memory


    'A': BLOCK_COUNT = BLOCK_5MIN = 5.6Mb
    'S': BLOCK_COUNT = BLOCK_15MIN = 17Mb
    'F': BLOCK_COUNT = BLOCK_30MIN = 34Mb
    'G': BLOCK_COUNT = BLOCK_1HR = 67Mb
    'H': BLOCK_COUNT = BLOCK_2HR = 133.5Mb
    'J': BLOCK_COUNT = BLOCK_4HR = 266.8Mb
    'K': BLOCK_COUNT = BLOCK_12HR = 800Mb
    'L': BLOCK_COUNT = BLOCK_24HR = 1.6Gb
    'a': BLOCK_COUNT = ~14 seconds = 262Kb

    The OpenBCI Processing sketch allows for selecting recording blocks from 'A' to 'L'. The small 'a' block allocation is for testing. You can use it if you like. Make sure the card is installed correctly on the OpenBCI board before you send the command to create the file. If you don't have the card installed, all is not lost! The program will hang until a valid card is installed and the file created. One of the nice things about writing the data in blocks is that once the block is written, it is on the card. In other words, if you create a file that allocates 30 minutes of record time and then stop your recording after only 15 minutes (by resetting the uC, or powering down the board, or pulling out the card) all of the data that was written will still be on the card!

    OpenBCI Formatting

    File Naming

    We are using the SDFat library, which limits our file name to the old 8.3 format (8 character file name, three character file type extension). OpenBCI automatically creates SD files with an incrementing counter as part of the file name. For example, the first file that you ever make with your OpenBCI board will be called OBCI_01.TXT and the next one will be called OBCI_02.TXT. The numbering counts up in Hexadecimal until you get to file OBCI_FF.TXT, the next file will be OBCI_00.TXT. So, you have up to 256 discreet files that you can make on the SD card before you overwrite anything. The file name counter values are saved in the Arduino and chipKIT EEPROM, and incremented every time you create a file.

    Data Logging Format

    We tried to make it as easy as possible to log the data, given the 512 block limitation. (A sample of a saved file is to the right) Because it's difficult to manage signed decimal values in a timely fashion, we are writing all of the data in hexadecimal. That also makes it easier to anticipate file size and record time. In the example you can see that each ADS channel value is a 24bit number separated by a comma. The Accelerometer/Aux values are 16bit, and only written when they get updated or are used (activated). In this example, the Accelerometer is sampling at 50Hz, while the ADS1299 is sampling at 250Hz.


    Sample#, 8 ADS Channel Values, 3 Accelerometer/Aux Values

    8B,028A3C,028A0E,028A86,028A04,0288FB,028AB7,028962,028A42
    8C,028A3D,028A09,028A89,028A08,0288FE,028AC5,028960,028A3C
    8D,028A3A,028A0B,028A85,028A01,0288ED,028AB1,02895A,028A3D
    8E,028A41,028A06,028A83,0289FE,0288F2,028AAD,028953,028A3A,02A0,FF80,21A0
    8F,028A42,028A02,028A79,0289FC,0288E8,028AAF,02894D,028A3F
    90,028A32,028A0C,028A7C,0289FF,0288EE,028AB4,028959,028A3A
    91,028A39,028A03,028A80,028A04,0288F6,028AB6,02894D,028A29
    92,028A3B,028A0C,028A84,028A04,0288F1,028ABE,028952,028A37
    93,028A3D,028A0F,028A7E,0289F6,0288EA,028AC2,02895A,028A35,02A0,FF80,2190
    94,028A40,028A11,028A76,028A03,0288E4,028ABD,028953,028A38

    The saved file also contains meta-data at the beginning and end. Lines of text start with a % symbol, so that conversion software will know they are just text. The first line time-stamps with the time in milliseconds since the board was turned on. If for any reason the streaming data is stopped during a recording session, The stop time will be inserted, and if re-started, there will be another start time stamp. At the end of the file there is a record of the total write time in milliseconds, and information about the block write performance: min block write and max block write in microseconds, as well as record of any blocks that took more than two milliseconds to write. Examples of the meta-data at right.


    %START AT
    00001C70
    00,8822D0,882E56,8CB903,8AA6B0,88101E,881459,8C9E38,8CC28A
    01,882194,882D1F,8CB47F,8AA0B5,880EE8,881321,8C9B2D,8CC403
    ....
    50,876554,8770E3,8BFE9F,891AE4,875316,875739,8BE3A1,8C0FE0
    %STOP AT
    000025BD
    %START AT
    0000315A
    00,866B60,8676F6,8B099A,86F099,8659F9,865DAA,8AE564
    01,866A24,8675B7,8B05B9,86E9D6,8658B7,865C68,8AE291
    ....
    %Total time mS:
    00005F53
    %min Write time uS:
    0000012B
    %max Write time uS:
    00000131
    %Over:
    00000000
    %block, uS

    The OpenBCI Processing Sketch has the functionality to read and convert these hexadecimal files to 'normal' data files.

    Writing to SD Card using the OpenBCI GUI

    Before starting the session, expand the dropdown in the "Write to SD Card?" section of the Control Panel with Cyton as the Data Source. Select the maximum file size in minutes. Note that the dropdown can scroll to show more options.

    WriteToSDGUIScreenshot

    Loading SD Card files for Playback using OpenBCI GUI

    SD file conversion is no longer necessary in GUI v5. Simply select an SD card file from the Cyton or Cyton+Daisy and it will load for playback!

    LoadSDCardPlaybackScreenshot

    Converting Hex files in OpenBCI GUI

    DEPRECATED -- Expand this dropdown for instructions to convert SD files using GUI v4.2.0

    Note: To convert very large recordings, you must run the OpenBCI_GUI Sketch in Processing after changing "Increase Maximum Available Memory to: " at least 9000 MB aka 9GB.

    We don't currently have a way to recall the file contents from the OpenBCI board over the Radio link to the Dongle. You must remove the SD card from the OpenBCI board and access the files via your computer.

    SelectFilePrompt

    On startup, the OpenBCI GUI will ask you for the data source you want to work with. Select PLAYBACK(from file) and click the SELECT SD FILE button.

    SelectSDfile

    Navigate to the OpenBCI generated file, and click OPEN. The GUI will convert the file you selected. The resulting file will be placed inside a file called EEG_Data in the Processing OpenBCI GUI Sketch Folder. The file naming convention is SDconverted-Year-Month-Day-Time.txt. Example:

    /Documents/OpenBCI_GUI/SDconverted-2015-01-14_13-35-54.txt

    - - + + \ No newline at end of file diff --git a/Cyton/CytonSDK/index.html b/Cyton/CytonSDK/index.html index e366ae69a..89d150d1f 100644 --- a/Cyton/CytonSDK/index.html +++ b/Cyton/CytonSDK/index.html @@ -12,8 +12,8 @@ Cyton Board SDK | OpenBCI Documentation - - + +
    @@ -53,7 +53,7 @@ User sends 0xF0 0x07 to get status

    Firmware v3.0.0 New Commands

    Supporting all v1.0.0 and v2.0.0, the v3.0.0 firmware extends the OpenBCI system to allow for a variable sample rate and analog or digital input readings!

    Sample Rate

    ~(COMMAND)
    This works similar to the Channel Settings commands, however, there is no latching character. Power cycling the OpenBCI board will cause the sample rate to reset back to default of 250Hz.

    IMPORTANT! The Cyton with USB Dongle cannot and will not stream data over 250SPS. Plug in the WiFi Shield to get speeds over 250SPS streaming. You may still write to an SD card though, the firmware will not send EEG data over the Bluetooth radios.

    COMMAND

    EXAMPLE

    First, user sends ~~

    returns Sample rate is 250Hz$$$

    Then, user sends ~5

    returns Sample rate set to 500Hz$$$

    NOTE: if not all commands are not received within 1 second, Timeout processing multi byte message - please send all commands at once as of v2$$$

    Board Mode

    /(COMMAND)
    This works similar to the sample rate. Power cycling the OpenBCI board will cause the board mode to return to default mode with accelerometer in the aux bytes.

    COMMAND

    EXAMPLE

    First, user sends //

    returns Board mode is default$$$

    Then, user sends /2

    returns Board mode set to analog$$$

    NOTE: if not all commands are not received within 1 second, Timeout processing multi byte message - please send all commands at once as of v2$$$

    Wifi Shield Commands

    {"{"}

    Try to attach a Wifi Shield

    returns Success will send response Success: Wifi attached$$$ on failure response will be Failure: Wifi not attached$$$. Failure happens when the wifi shield is not powered up or the wifi shield does not power correctly. Try power cycling the system if failure continues.

    {"}"}

    Remove an attached wifi shield.

    returns Success will send response Success: Wifi removed$$$ on failure response will be Failure: Wifi not removed$$$. Failure occurs when no wifi shield is present to remove.

    :

    Get the status of the wifi shield, will either be connected or not connected.

    returns With wifi shield successfully attached will send response Wifi present$$$. If there is no OpenBCI board attached, will send Wifi not present, send { to attach the shield$$$.

    ;

    Perform a soft reset of the Wifi shield. Will do a power on reset of just the wifi shield.

    Get Version

    V To get firmware version

    returns v3.1.1$$$

    Unused ASCII Characters

    These are currently unused (and user available) characters in the OpenBCI Cyton platform:

    9 ( ) _ o O f g h k l ' " n N M , . (space)

    - - + + \ No newline at end of file diff --git a/Cyton/CytonSpecs/index.html b/Cyton/CytonSpecs/index.html index 359476d69..efcb1af4f 100644 --- a/Cyton/CytonSpecs/index.html +++ b/Cyton/CytonSpecs/index.html @@ -12,8 +12,8 @@ Cyton Specs | OpenBCI Documentation - - + +
    @@ -25,7 +25,7 @@ Daisy Layer2 Daisy Layer3 Daisy LayerBottom

    Daisy Module PCB Files

    OpenBCI Daisy Module Gerber Files

    - - + + \ No newline at end of file diff --git a/Deprecated/8bitBoardDep/index.html b/Deprecated/8bitBoardDep/index.html index 4b753d331..f5385ec47 100644 --- a/Deprecated/8bitBoardDep/index.html +++ b/Deprecated/8bitBoardDep/index.html @@ -12,8 +12,8 @@ OpenBCI 8bit Board (no longer in production) | OpenBCI Documentation - - + +
    @@ -21,7 +21,7 @@ 8bit PCB Layer2 8bit PCB Layer3 8bit PCB LayerBOTTOM

    8bit Board PCB Files

    OpenBCI 8bit gerber & BOM (568K zip)

    - - + + \ No newline at end of file diff --git a/Deprecated/DeprecatedLanding/index.html b/Deprecated/DeprecatedLanding/index.html index 51cd36113..1fea40c2b 100644 --- a/Deprecated/DeprecatedLanding/index.html +++ b/Deprecated/DeprecatedLanding/index.html @@ -12,13 +12,13 @@ Deprecated Docs | OpenBCI Documentation - - + +
    Skip to main content
    - - + + \ No newline at end of file diff --git a/Deprecated/Hub/index.html b/Deprecated/Hub/index.html index 8a0e0df90..f37e62aa9 100644 --- a/Deprecated/Hub/index.html +++ b/Deprecated/Hub/index.html @@ -12,8 +12,8 @@ OpenBCI Hub | OpenBCI Documentation - - + +
    @@ -181,7 +181,7 @@ As of v1.0.0

    message

    The string message from the Ganglion.

    Example:


    {
    "code": 200
    "type": "message",
    "message": "Hello, world!",
    "value": 300
    }

    Samples

    type: data

    Description: Sample from the boards.

    Availability: As of v1.0.0

    startByte

    Number should be 0xA0

    sampleNumber

    a Number between 0-255

    channelData

    channel data indexed at 0 filled with floating point Numbers in Volts) if sendCounts is false

    channelDataCounts

    channel data indexed at 0 filled with un scaled integer Numbers in raw ADS counts) if sendCounts is true

    accelData

    Array with X, Y, Z accelerometer values when new data available) if sendCounts is false

    accelDataCounts

    Array with X, Y, Z accelerometer values when new data available) Only present if sendCounts is true

    auxData

    Buffer filled with either 2 bytes (if time synced) or 6 bytes (not time synced)

    stopByte

    Number should be 0xCx where x is 0-15 in hex

    boardTime

    Number the raw board time

    timestamp

    Number the boardTime plus the NTP calculated offset

    Example for gangliom:


    {
    "code": 200,
    "type": "data",
    "channelDataCounts": [0, 1, 2, 3]
    }

    Example for Cyton with accel:


    {
    "code": 200,
    "type": "data",
    "channelDataCounts": [0, 1, 2, 3, 4, 5, 6, 7],
    "accelDataCounts": [0, 1, 2],
    "stopByte": 192
    }

    Example for Cyton with Daisy in analog read mode:


    {
    "auxData": {
    "lower": {
    "data": [ 1, 215, 1, 45, 3, 250],
    "type": "Buffer"
    },
    "upper": {
    "data": [ 1, 215, 1, 44, 3, 251],
    "type": "Buffer"
    }
    },
    "valid": true,
    "code": 204,
    "stopByte": 193,
    "_timestamps": {
    "lower": 1543879978994,
    "upper": 1543879978994
    },
    "channelDataCounts": [-7729993, -7649407, -7606327, -7571616, -7591709, -7687549, -7552756, -7590690, -7580998, -7556930, -7596914, -7549892, -7594576, -7658804, -7523426, -7662588],
    "type": "data",
    "sampleNumber": 52,
    "timestamp": 1543879978994
    }

    - - + + \ No newline at end of file diff --git a/Deprecated/MarkIII/index.html b/Deprecated/MarkIII/index.html index 44d838358..3025de94d 100644 --- a/Deprecated/MarkIII/index.html +++ b/Deprecated/MarkIII/index.html @@ -12,8 +12,8 @@ Ultracortex Mark III | OpenBCI Documentation - - + +
    @@ -33,7 +33,7 @@ image image image

    Cut Zip Ties

    Turn the ULTRACORTEX over and snip off all of the loose ends of the zip ties.

    image

    Insert Comfort Nodes

    Next, screw a comfort node into each of the 8 QUADSTARS.

    image

    Supernova Assembly Complete!

    image

    Adjust the Ultracortex for your head

    Put the Ultracortex Mark 3 onto your head and gradually tighten the electrode units until the electrodes are snuggly (but comfortably) against your scalp. If it is difficult to twist the OCTABOLT pieces by hand, you may need to use the OCTATOOL as seen in the gif below.

    Be careful not to strain the electrode wires when twisting the electrode unit with the OCTATOOL, or you may separate the wire from the electrode itself. Turn the OCTABOLT until the wire is nearly taught, then reposition the wire and tool and twist again, as demonstrated in the gif.

    image

    Examine your brain waves!

    Place your UltraCortex on your head so that the back center node is roughly the same distance above your inion (bump on the back of your skull) as the front center node is above the bridge of your nose. As you place the UltraCortex on your head, the springs should adjust to the shape and size of your head.

    Now that you have your Ultracortex assembled and comfortably adjusted to your head size and shape, it's brain wave time!

    image

    Check out the Getting Started w/ OpenBCI tutorial to get up-and-running with the OpenBCI Processing GUI.

    Below is a screenshot of what the GUI looks like when you've got your OpenBCI + Ultracortex (w/ 8 channels) hooked up! You can see a nice alpha (~11 hz) spike on the FFT Plot.

    image

    Give Us Feedback!

    If you have questions, comments, or suggestions regarding the printing and/or assembly of the Ultracortex, we'd love to hear from you. Please submit issues to this repository or email us at contact@openbci.com. Or take some pictures of yourself wearing the Ultracortex and Tweet at us (@OpenBCI & @Ultracortex)!

    - - + + \ No newline at end of file diff --git a/Deprecated/MyoCyton/index.html b/Deprecated/MyoCyton/index.html index 6ec5d1e1d..0de7aad58 100644 --- a/Deprecated/MyoCyton/index.html +++ b/Deprecated/MyoCyton/index.html @@ -12,15 +12,15 @@ MyoWare OpenBCI Integration (Cyton Board) | OpenBCI Documentation - - + +
    Skip to main content

    MyoWare OpenBCI Integration (Cyton Board)

    THIS HARDWARE VERSION HAS BEEN DEPRECATED AND IS NO LONGER IN PRODUCTION.

    MyoWare v1.0 is obsolete and has been pulled from production. The updated version is Myoware v2.0. This doc covers the integration of MyoWare v1.0 with the Cyton board.

    Overview

    This tutorial will show you how to read EMG data (electrical signals from muscles) using a MyoWare board, an OpenBCI Cyton board, and the OpenBCI GUI. If you have a Ganglion board instead, check out our Ganglion board MyoWare integration tutorial!

    MyoWare Board

    Materials Needed

    1. MyoWare board
    2. OpenBCI Cyton board, with power source
    3. OpenBCI dongle
    4. Skintact sticky electrodes (for using the MyoWare board)
    5. Soldering iron and materials
    6. Two male-male jumper wires (like these), and three male-female jumper wires (like these)

    Note: jumper wires aren't sold on the OpenBCI website, but we used some from Adafruit (linked above) for this tutorial

    1. Soldering the MyoWare Headers

    Solder 5 wires to the MyoWare board as shown below. Solder the male-male wires to the "+" and "-" connects, and the male-female wires to the R, E, and M connects.

    MyoWare Board post-soldering

    The wires attached to the "+" and "-" connects will be used to supply power to the board. They'll be attached to high voltage and ground outputs on the OpenBCI Cyton board.

    The wires attached to the R, E, and M connects will transmit electrical signals from MyoWare's three electrodes to the OpenBCI Cyton board. R is the reference electrode, the one attached to the black wire. M is the middle electrode, and E is the end electrode. The E and M electrodes will measure activity across a muscle.

    2. Preparing OpenBCI Cyton Board

    Your Cyton board should look like this:

    Board with Headers

    If your Cyton board is missing the black, female pin connectors (called "headers") sticking out of the board, you will need to solder them on before continuing.

    3. Wiring the MyoWare Board to the OpenBCI Cyton Board

    Connect the 5 wires from the MyoWare board in step 1 to the OpenBCI board, as shown below:

    Board with Headers

    The "+" and "-" from the MyoWare board should go to DVDD and GND connects on the left side of the Cyton board. R, E, and M will connect to the pins at the top.

    The wires should be connected like this:

    MyoWare BoardOpenBCI Board
    +DVDD
    -GND
    RBIAS (top pin)
    EN1P Top
    MN1P Bottom

    R, "+", and "-" must always go to the pins shown above. E and M can also be connected to N2P top and N2P bottom, or N3P top and N3P bottom, or any of the other two "NXP" pins.

    When you have everything wired up, set the power switch on the MyoWare board to "on". Turn on the OpenBCI board, connect the USB dongle to your computer, and start the OpenBCI GUI software. If you're new to using an OpenBCI board with your computer, take a look at the Cyton Getting Started Guide.

    4. Streaming EMG Data with the OpenBCI GUI

    Attach three Skintact electrodes to the three electrodes on the MyoWare board, and then stick the board on a muscle you'd like to monitor. The adafruit MyoWare tutorial has good guidelines for MyoWare board placement: (https:).

    You'll be able to see signals from the MyoWare electrodes in the OpenBCI GUI. If you connected E and M to the N1P pins on the OpenBCI board, then the MyoWare data will appear in channel 1.

    Here's what the GUI, and channel 1, will look like with the muscle at rest:

    Resting

    And here's what channel 1 will look like after flexing the muscle:

    Firing

    5. Using OpenBCI's EMG GUI Widget

    The OpenBCI GUI also has a widget for visualizing EMG data. To view it, click on the drop down menu under "FFT Plot", and select "EMG" instead:

    Each circle and box represents a channel. The circle and box fill up as the intensity of the signal on that channel increases.

    Here's what happens to the GUI when a muscle is flexed a little (top) or very strongly (bottom):

    You can use these changes in signal intensity to trigger analog or digital events from within the GUI as you like. Check out the W_EMG.pde file for more information on the EMG widget.

    - - + + \ No newline at end of file diff --git a/Deprecated/MyoGanglion/index.html b/Deprecated/MyoGanglion/index.html index 0dff7b6f9..406062bd1 100644 --- a/Deprecated/MyoGanglion/index.html +++ b/Deprecated/MyoGanglion/index.html @@ -12,13 +12,13 @@ MyoWare OpenBCI Integration (Ganglion Board) | OpenBCI Documentation - - + +
    Skip to main content

    MyoWare OpenBCI Integration (Ganglion Board)

    THIS HARDWARE VERSION HAS BEEN DEPRECATED AND IS NO LONGER IN PRODUCTION.

    MyoWare v1.0 is obsolete and has been pulled from production. The updated version is Myoware v2.0. This doc covers the integration of MyoWare v1.0 with the Cyton board.

    Overview

    This tutorial will show you how to read EMG data (electrical signals from muscles) using a MyoWare board, an OpenBCI Ganglion board, and the OpenBCI GUI. If you have a Cyton board instead, check out our Cyton board MyoWare integration tutorial!

    MyoWare + Ganglion supplies

    Materials Needed

    1. MyoWare board
    2. OpenBCI Ganglion board, with power source
    3. Skintact sticky electrodes (for using the MyoWare board)
    4. Soldering iron and materials
    5. Two male-male jumper wires (like these), and three male-female jumper wires (like these)

    Note: jumper wires aren't sold on the OpenBCI website, but we used the ones from Adafruit (linked above) for this tutorial

    1. Soldering the MyoWare Headers

    Solder 5 wires to the MyoWare board as shown below. Solder the male-male wires to the "+" and "-" connects, and the male-female wires to the R, E, and M connects.

    MyoWare Board post-soldering

    The wires attached to the "+" and "-" connects will be used to supply power to the board. They'll be attached to high voltage and ground outputs on the OpenBCI Ganglion board.

    The wires attached to the R, E, and M connects will transmit electrical signals from MyoWare's three electrodes to the OpenBCI Ganglion board. R is the reference electrode, the one attached to the black wire. M is the middle electrode, and E is the end electrode. The E and M electrodes will measure activity across a muscle.

    2. Preparing OpenBCI Ganglion Board

    Remove the transparent yellow stickers from the four switches on the front of the Ganglion Board.

    3. Wiring the MyoWare Board to the OpenBCI Ganglion Board

    Connect the 5 wires from the MyoWare board in step 1 to the Ganglion board, as shown below:

    Board with Headers

    The "+" and "-" from the MyoWare board should go to the DVDD and GNDA connects on the left side of the Ganglion board. R, E, and M will connect to the pins at the top.

    The wires should be connected like this:

    MyoWare BoardOpenBCI Ganglion Board
    +DVDD
    -GNDA
    RD_G (top pin)
    E1- (bottom pin)
    M1+ (top pin)

    R, "+", and "-" must always go to the pins shown above. E and M can also be connected to 2+ and 2- (the top and bottom "2" pins), or 3+ and 3-, or 4+ and 4-.

    When you have everything wired up, set the power switch on the MyoWare board to "on". Turn on the OpenBCI Ganglion board, turn on your computer's Bluetooth feature, and start the OpenBCI GUI software. If you're new to using a Ganglion board with your computer, take a look at the Ganglion Getting Started Guide.

    4. Streaming EMG Data with the OpenBCI GUI

    Attach three Skintact electrodes to the three electrodes on the MyoWare board, and then stick the board on a muscle you'd like to monitor. The Adafruit MyoWare tutorial has good guidelines for MyoWare board placement: (https:).

    You'll be able to see signals from the MyoWare electrodes in the OpenBCI GUI. If you connected E and M to the 1- and 1+ pins on the OpenBCI Ganglion board, then the MyoWare data will appear in channel 1.

    Here's what the GUI, and channel 1, will look like with the muscle at rest:

    Resting

    And here's what channel 1 will look like after flexing the muscle:

    Firing

    5. Using OpenBCI's EMG GUI Widget

    The OpenBCI GUI also has a widget for visualizing EMG data. To view it, click on the drop down menu under "FFT Plot", and select "EMG" instead:

    Ganglion EMG Before Flex

    Each circle and box represents a channel. The circle and box fill up as the intensity of the signal on that channel increases.

    Here's what happens to the GUI when a muscle is flexed:

    Ganglion EMG After Flex

    You can use this change in signal intensity to trigger analog or digital events from within the GUI as you like. Check out the W_EMG.pde file for more information on the EMG widget.

    Still have questions? Post on our Forum or let us know at contact@openbci.com!

    - - + + \ No newline at end of file diff --git a/Deprecated/Python/index.html b/Deprecated/Python/index.html index f07862fda..28eadef3f 100644 --- a/Deprecated/Python/index.html +++ b/Deprecated/Python/index.html @@ -12,13 +12,13 @@ Python and OpenBCI | OpenBCI Documentation - - + +
    Skip to main content

    Python and OpenBCI

    THIS DOCUMENT HAS BEEN DEPRECATED. PLEASE REFER TO "FOR DEVELOPERS" SECTION FOR INFORMATION ON BRAINFLOW-PYTHON.

    OpenBCI has a Python software library designed to work with OpenBCI hardware. To use it, download our OpenBCI Python github repository: https: DEPRECATED. This Python code is meant to be used by people familiar with Python and programming in general. Its purpose is to allow for programmers to interface with OpenBCI technology directly, both to acquire data and to write programs that can use that data in a live setting, using Python.The OpenBCI-Python repo is still live but it is not longer being mantained by OpenBCI.

    Please direct any questions, suggestions and bug reports to the github repo - DEPRECATED as well.

    pyOpenBCI - DEPRECATED

    This repo has been designed to be a more beginner friendly version of the OpenBCI-Python repo. If there is anything you think we should add please open an issue.

    Using this repo provides a building block for developing with Python. The goal for the Python library is to provide a stable Python driver for all OpenBCI Biosensors, that:

    • Allows Python users to install one module and use any board they choose
    • Provides examples of using Python to port data to other apps like lab streaming layer
    • Performs the heavy lifting when extracting and transforming raw binary byte streams
    • Provides a base for the beginner users to use Python to process their OpenBCI data

    To Do

    • Add Ganglion Aux Data

    Requirements

    • Python 2.7 or 3.4+
    • Currently the Cyton works on Windows, Linux, and MacOS.
    • Ganglion works on Linux only (Linux VM with enabled Bluetooth works as well).
    • The WiFi shield is known to have reliability issues across different computer configurations. Using it effectively requires advanced technical skills and programming knowledge. Note that the code avaiable here has not been tested accross all platforms.

    Installation

    First, make sure you have the necessary dependencies.


    pip install numpy pyserial bitstring xmltodict requests

    Linux users may need bluepy also.

    Then you can use pip to install the OpenBCI module.


    pip install pyOpenBCI

    Once installed, try running the examples provided to make sure you can connect to your OpenBCI board.

    Important notes

    Currently the Ganglion board can only be used with a Linux OS. The WiFi shield is known to have reliability issues across different computer configurations. Using it effectively requires advanced technical skills and programming knowledge. Note that the code avaiable here has not been tested accross all platforms.

    Getting Started

    First you need to initialize your board with one of the following commands:

    For Cyton board:


    # For Windows replace '*' with the port number
    board = OpenBCICyton(port='COM*')

    # For MacOS and Linux replace '*' with the port number
    board = OpenBCICyton(port='/dev/ttyUSB*')

    To find the COM port you are connected to you can use the OpenBCI GUI. Otherwise you can leave the port number as None, and the function find_port() will run and connect to the first Cyton Dongle it finds.

    For Cyton + Daisy:


    # For Windows replace '*' with the port number
    board = OpenBCICyton(port='COM*', daisy=True)

    # For MacOS and Linux replace '*' with the port number
    board = OpenBCICyton(port='/dev/ttyUSB*', daisy=True)

    To find the COM port you are connected to you can use the OpenBCI GUI. Otherwise you can leave the port number as None, and the function find_port() will run and connect to the first Cyton Dongle it finds.

    For Ganglion:


    # For Linux replace '*' with the mac address.
    board = OpenBCIGanglion(mac='*')

    If you need to find the Ganglion mac address you can use an app like nRF connect to find the ganglion. Otherwise you can leave the mac address as None, and the function find_mac() will run (NOTE: You will need to run the script with sudo for this function to work).

    For Wifi Shield:


    board = OpenBCIWifi(shield_name='OpenBCI-2254', sample_rate=200)

    Sending commands

    Once you initialize the board you can use the commands on the OpenBCI SDKs (Ganglion, Cyton, Wifi Shield) to send commands to the board using python (make sure your commands are strings).


    # Write commands to the board
    board.write_command(command)

    Here is a table of the most common ones:

    Ganglion SDKCyton SDKCyton & Daisy SDK (Additional Commands)Wifi Shield SDK (Additional Commands)
    Turn Channels OFF1 2 3 41 2 3 4 5 6 7 8q w e r t y u i
    Turn Channels ON! @ # $ % ^ & *Q W E R T Y U I
    Connect to internal GND0
    Enable Synthetic Square Wave[[
    Disable Synthetic Square Wave]]
    Connect to DC Signalp
    Set Channels to Defaultd
    Start Streaming Databb
    Stop Streaming Datass
    Soft Resetvv;
    Enable Accelerometern
    Disable AccelerometerN

    Initializing Stream

    To start your stream you can use the following command with a callback function. You can look at the examples folder for some pre-written callback functions.


    # Start stream
    board.start_stream(callback)

    The output of the start_stream function is the OpenBCISample on the callback function. The OpenBCISample object has the following attributes:

    • packet_id = The ID of the incomming packet.
    • channels_data = The raw EEG data of each channel. 4 for the Ganglion, 8 for the Cyton, and 16 for the Cyton + Daisy.
    • aux_data = Accelerometer data.

    Because the channels_data and aux_data is the raw data in counts read by the board, we need to multiply the data by a scale factor. There is a specific scale factor for each board:

    For the Cyton and Cyton + Daisy boards:

    Multiply uVolts_per_count to convert the channels_data to uVolts.


    uVolts_per_count = (4500000)/24/(2**23-1) #uV/count

    Multiply accel_G_per_count to convert the aux_data to G.


    accel_G_per_count = 0.002 / (2**4) #G/count

    For the Ganglion Board

    Multiply Volts_per_count to convert the channels_data to Volts.


    Volts_per_count = 1.2 * 8388607.0 * 1.5 * 51.0 #V/count

    Multiply accel_G_per_count to convert the aux_data to G.


    accel_G_per_count = 0.032 #G/count

    For the Wifi Shield

    The Wifi Shield already outputs the data in Volts and the aux data in G.

    Example (Print Raw Data)

    To test this example, use py Examples\print_raw_example.py or Examples\print_raw_example.py.


    from pyOpenBCI import OpenBCICyton

    def print_raw(sample):
    print(sample.channels_data)

    board = OpenBCICyton(port='COM5', daisy=False)

    board.start_stream(print_raw)

    Example (Simple LSL Streamer)

    To run this example, use py Examples\lsl_example.py or python Examples\lsl_example.py.


    from pyOpenBCI import OpenBCICyton
    from pylsl import StreamInfo, StreamOutlet
    import numpy as np

    SCALE_FACTOR_EEG = (4500000)/24/(2**23-1) #uV/count
    SCALE_FACTOR_AUX = 0.002 / (2**4)


    print("Creating LSL stream for EEG. \nName: OpenBCIEEG\nID: OpenBCItestEEG\n")

    info_eeg = StreamInfo('OpenBCIEEG', 'EEG', 8, 250, 'float32', 'OpenBCItestEEG')

    print("Creating LSL stream for AUX. \nName: OpenBCIAUX\nID: OpenBCItestEEG\n")

    info_aux = StreamInfo('OpenBCIAUX', 'AUX', 3, 250, 'float32', 'OpenBCItestAUX')

    outlet_eeg = StreamOutlet(info_eeg)
    outlet_aux = StreamOutlet(info_aux)

    def lsl_streamers(sample):
    outlet_eeg.push_sample(np.array(sample.channels_data)*SCALE_FACTOR_EEG)
    outlet_aux.push_sample(np.array(sample.aux_data)*SCALE_FACTOR_AUX)

    board = OpenBCICyton(port='COM5', daisy=False)

    board.start_stream(lsl_streamers)


    Who are we?

    The founder of the OpenBCI Python repository is Jermey Frey. The Python driver is one of the most popular repositories and has the most contributors!

    The contributors to these repos are people using Python mainly for their data acquisition and analytics.

    Contact us

    If you want to report a problem or suggest an enhancement we'd love for you to open an issue at this github repository because then we can get right on it.

    Glossary

    OpenBCI boards are commonly referred to as biosensors. A biosensor converts biological data into digital data.

    The [Ganglion][link_shop_ganglion] has 4 channels, meaning the Ganglion can take four simultaneous voltage readings.

    The [Cyton][link_shop_cyton] has 8 channels and [Cyton with Daisy][link_shop_cyton_daisy] has 16 channels.

    Generally speaking, the Cyton records at a high quality with less noise. Noise is anything that is not signal.

    Thank you

    Thank you so much (Danke schรถn! Merci beaucoup!) for visiting the project and we do hope that you'll join us on this amazing journey to make programming with OpenBCI fun and easy.

    License

    MIT

    link_shop_wifi_shield

    link_shop_ganglion

    link_shop_cyton

    link_shop_cyton_daisy

    - - + + \ No newline at end of file diff --git a/Deprecated/SpiderclawDep/index.html b/Deprecated/SpiderclawDep/index.html index 6a891afcc..f7fa61000 100644 --- a/Deprecated/SpiderclawDep/index.html +++ b/Deprecated/SpiderclawDep/index.html @@ -12,13 +12,13 @@ Spiderclaw V1 & V2 (deprecated) | OpenBCI Documentation - - + +
    Skip to main content
    - - + + \ No newline at end of file diff --git a/Deprecated/UltracortexMark1Dep/index.html b/Deprecated/UltracortexMark1Dep/index.html index dc40e7cc2..c97e98141 100644 --- a/Deprecated/UltracortexMark1Dep/index.html +++ b/Deprecated/UltracortexMark1Dep/index.html @@ -12,13 +12,13 @@ Ultracortex Mark 1 | OpenBCI Documentation - - + +
    Skip to main content

    Ultracortex Mark 1

    Files related to the ultracortex, the 3D-printable EEG headset compatible with OpenBCI (currently under development).

    The electrodes seen in the photos here are dry electrodes from Florida Research Instruments (FRI), found here.

    The FRI_electrode_mount.stl was modeled to serve as a mechanical mount for the FRI electrodes.

    The screws and nuts used to fasten the FRI electrode to the FRI_electrode_mount are:

    Image References

    image

    image

    image

    image

    image

    image

    image

    - - + + \ No newline at end of file diff --git a/Deprecated/UltracortexMark2Dep/index.html b/Deprecated/UltracortexMark2Dep/index.html index e29103719..ebc9136af 100644 --- a/Deprecated/UltracortexMark2Dep/index.html +++ b/Deprecated/UltracortexMark2Dep/index.html @@ -12,8 +12,8 @@ Ultracortex Mark 2 | OpenBCI Documentation - - + +
    @@ -26,7 +26,7 @@ image image image

    - - + + \ No newline at end of file diff --git a/Deprecated/UltracortexMark3Dep/index.html b/Deprecated/UltracortexMark3Dep/index.html index f0b60a779..ecbd378e6 100644 --- a/Deprecated/UltracortexMark3Dep/index.html +++ b/Deprecated/UltracortexMark3Dep/index.html @@ -12,8 +12,8 @@ Ultracortex Mark 3 | OpenBCI Documentation - - + +
    @@ -31,7 +31,7 @@ image

    Slide your spring and then the OCTABOLT around the wire as shown below. image

    Snap the full electrode unit together, guiding the semi-spherical protrusions on the outside of the SPRING_CASING into the relief cuts of the OCTABOLT. image

    Voila! Spring-loaded electrode GIF!

    image

    Insert electrode units into your Ultracortex

    Once you've asesembled all of your electrode units, twist them into their respective Ultracortex frame nodes. If the parts are tough to twist into place by hand, use the OCTATOOL that comes with your kit as shown in the picture below. Over time the resistance between the OCTANUT and OCTABOLT will diminish, and the pieces will twist into place more easily.

    image

    Reconnect wires to OpenBCI & connect ear clip electrodes (Reference & Ground)

    Now that all of your electrode units are connected to your Ultracortex frame, reconnect the electrode wires to the OpenBCI board as detailed above. If you have some handy, you may want to use zip ties to secure the loose wiring to the Ultracortex frame. Later revisions of the headset will be designed to account for this. ;)

    image

    Next, connect two touch-proof adapter cables to SRB1 and bottom BIAS pin (white and black respectively in the image below). You can use the touch-proof adapter that comes with the OpenBCI 32bit Board or OpenBCI 16-channel R&D Kit. Then connect your ear clip electrodes to these touch-proof adapters. These ear clip electrodes serve as the reference and bias (ground with common-mode noise rejection) for your EEG system.

    image

    Fasten the BOARD_COVER

    Now clip your board cover into place. If you've soldered any of the header rows onto your OpenBCI board, you'll need to use the BOARD_COVER_ADVANCED, as seen in the picture below. Otherwise, you can use the BOARD_COVER_STANDARD with the OpenBCI logo.

    image

    Adjust the Ultracortex for your head

    Put the Ultracortex Mark 3 onto your head and gradually tighten the electrode units until the electrodes are snuggly (but comfortably) against your scalp. If it is difficult to twist the OCTABOLT pieces by hand, you may need to use the OCTATOOL as seen in the gif below.

    Be careful not to strain the electrode wires when twisting the electrode unit with the OCTATOOL, or you may separate the wire from the electrode itself. Turn the OCTABOLT until the wire is nearly taught, then reposition the wire and tool and twist again, as demonstrated in the gif.

    image

    Examine your brain waves!

    Now that you have your Ultracortex assembled and comfortably adjusted to your head size and shape, it's brain wave time!

    image

    Check out the Getting Started w/ OpenBCI tutorial to get up-and-running with the OpenBCI Processing GUI.

    Below is a screenshot of what the GUI looks like when you've got your OpenBCI + Ultracortex (w/ 8 channels) hooked up! You can see a nice alpha (~11 hz) spike on the FFT Plot.

    image

    Give Us Feedback!

    If you have questions, comments, or suggestions regarding the printing and/or assembly of the Ultracortex, we'd love to hear from you. Please submit issues to this repository or email us at contact@openbci.com. Or take some pictures of yourself wearing the Ultracortex and Tweet at us (@OpenBCI & @Ultracortex)!

    - - + + \ No newline at end of file diff --git a/Deprecated/UltracortexMark3_NovaDep/index.html b/Deprecated/UltracortexMark3_NovaDep/index.html index 7233e3cb6..b3faa819a 100644 --- a/Deprecated/UltracortexMark3_NovaDep/index.html +++ b/Deprecated/UltracortexMark3_NovaDep/index.html @@ -12,8 +12,8 @@ Ultracortex Mark III Nova and Supernova | OpenBCI Documentation - - + +
    @@ -33,7 +33,7 @@ image image image

    Cut Zip Ties

    Turn the ULTRACORTEX over and snip off all of the loose ends of the zip ties.

    image

    Insert Comfort Nodes

    Next, screw a comfort node into each of the 8 QUADSTARS.

    image

    Supernova Assembly Complete!

    image

    Adjust the Ultracortex for your head

    Put the Ultracortex Mark 3 onto your head and gradually tighten the electrode units until the electrodes are snuggly (but comfortably) against your scalp. If it is difficult to twist the OCTABOLT pieces by hand, you may need to use the OCTATOOL as seen in the gif below.

    Be careful not to strain the electrode wires when twisting the electrode unit with the OCTATOOL, or you may separate the wire from the electrode itself. Turn the OCTABOLT until the wire is nearly taught, then reposition the wire and tool and twist again, as demonstrated in the gif.

    image

    Examine your brain waves!

    Place your UltraCortex on your head so that the back center node is roughly the same distance above your inion (bump on the back of your skull) as the front center node is above the bridge of your nose. As you place the UltraCortex on your head, the springs should adjust to the shape and size of your head.

    Now that you have your Ultracortex assembled and comfortably adjusted to your head size and shape, it's brain wave time!

    image

    Check out the Getting Started w/ OpenBCI tutorial to get up-and-running with the OpenBCI Processing GUI.

    Below is a screenshot of what the GUI looks like when you've got your OpenBCI + Ultracortex (w/ 8 channels) hooked up! You can see a nice alpha (~11 hz) spike on the FFT Plot.

    image

    Give Us Feedback!

    If you have questions, comments, or suggestions regarding the printing and/or assembly of the Ultracortex, we'd love to hear from you. Please submit issues to this repository or email us at contact@openbci.com. Or take some pictures of yourself wearing the Ultracortex and Tweet at us (@OpenBCI & @Ultracortex)!

    - - + + \ No newline at end of file diff --git a/Examples/CommunityPageProjects/index.html b/Examples/CommunityPageProjects/index.html index c565affe3..5801bd86d 100644 --- a/Examples/CommunityPageProjects/index.html +++ b/Examples/CommunityPageProjects/index.html @@ -12,13 +12,13 @@ Community Page Projects | OpenBCI Documentation - - + +
    Skip to main content

    Community Page Projects

    Head over to the Community Page for project tutorials contributed by OpenBCI Community members! Use the "tutorials" tag to filter.

    In the community page, search for "EMG OpenBCI" and you'll find, for example, how-tos on EMG-controlled Neurobots Battle Royale and EEG-controlled Shark as shown in IEEE Spectrum.

    You'll also find full walk-throughs on how to replicate award-winning SSVEP and P300-based neuroscience projects, such as the hands-free, brain-computer interface speller by McGill University Neurotech, the SSVEP-based communicator by University of Waterloo, and the P300-based speller by UCLA.

    - - + + \ No newline at end of file diff --git a/Examples/EEGProjects/FocusArduino/index.html b/Examples/EEGProjects/FocusArduino/index.html index 26248c990..e0695e845 100644 --- a/Examples/EEGProjects/FocusArduino/index.html +++ b/Examples/EEGProjects/FocusArduino/index.html @@ -12,14 +12,14 @@ Send Focus Data from GUI to Arduino | OpenBCI Documentation - - + +
    Skip to main content

    Send Focus Data from GUI to Arduino

    This tutorial shows you how to get started streaming data from the OpenBCI_GUI's Focus Widget via Serial connection to an Arduino UNO Rev3. Head HERE to find the OpenBCI/Arduino Focus Data tutorial in the updated Instructable format!

    What do I need?

    Helpful Background Skills

    Step 1 - Load the Example in the Arduino IDE

    The OpenBCI_GUI-FocusArduino.ino file is designed to serve as a simple starting point for creating your own Arduino project using data from the GUI over serial.

    You can copy/paste the code from Github into the Arduino IDE or download the Docs and navigate to the example /OpenBCI_files/OpenBCI_GUI-FocusArduino/OpenBCI_GUI-FocusArduino.ino.

    Step 2 - Upload the Arduino sketch

    Upload Arduino Sketch

    After uploading the sketch, you can close or minimize the Arduino IDE, but keep the Arduino connected to the computer. The sketch we just uploaded is running!

    Step 3 - Open OpenBCI_GUI in Synthetic Mode

    Open GUI Synthetic Mode

    Step 4 - Start Streaming

    Open and Setup the Networking Widget

    Setup Networking Widget

    Open the Focus Widget. Then, click "Start Data Stream" and then "Start" in the Networking Widget.

    OpenBCI Serial Not Focused

    Next, turn off channels 5 through 8 to simulate Relaxed state.

    The Arduino's built-in LED should blink when the Focus Widget reads Relaxing.

    OpenBCI Serial Focused

    Step 5 - Learn! Create! Share!

    From here, you can add more to your new Arduino project to react to Focus data from the OpenBCI_GUI:

    - - + + \ No newline at end of file diff --git a/Examples/EEGProjects/MotorImagery/index.html b/Examples/EEGProjects/MotorImagery/index.html index 2bb376a89..4bf3783cd 100644 --- a/Examples/EEGProjects/MotorImagery/index.html +++ b/Examples/EEGProjects/MotorImagery/index.html @@ -12,8 +12,8 @@ Motor Imagery | OpenBCI Documentation - - + +
    @@ -26,7 +26,7 @@ To delete a node select it and press 'delete' key. To add a new node, right click and type 'import xdf'. You can connect a new node to next node by dragging the outer semicircle to the next node.

    Import XDF

    Replace the Import Set with Import XDF

    Enter the calibration data filename and fill in the appropriate filename of the XDF file in the window.

    Picking up Marker Streams with LSL

    LSL Input

    Node: LSL Input

    The LSL Input node is responsible for returning a marker stream together with the EEG. Enter the name of the OpenBCI stream in the query and after you import the .xdf calibration data, you are ready to go.

    Streaming the Data

    OSC Output

    Connect an OSC (Open sound control) Output node to the Logistic Regression node in the pipeline designer and configure it as shown below before you stream the data.

    OSC Number_Output

    OSC(Open Sound Control) output Type in the IP address of the device to which you want to stream the data, which can be either an Arduino or a Raspberry Pi). Use 127.0.0.1 as an IP address if you want to receive the data on your local computer.

    Here is a python code to receive the streamed data on the local computer.

    Running NeuroPype Pipeline

    NeuroPype Icon

    We are in the final stage of the Motor Imagery Classification pipeline design. Now right click on the NeuroPype icon in the taskbar and click run pipeline. Navigate to your file path and select your edited pipeline simplemotorimagery.pyp and run it.

    If everything is configured properly, you will get two windows showing the Classification and Misclassification Rate. You can now see real-time predictions of either left or right on the windows. Imagine moving your right arm to increase the amplitude power of the right prediction and imagine moving your left arm to increase the amplitude power of the left prediction.

    Classification Icon

    When you run the python script on your local computer, you should receive the prediction data as shown below.

    OSC output from python script

    The car above uses NodeMCU and L298N motor driver. The NodeMCU coded in Arduino IDE and the code is mentioned below. To learn how to use NodeMCU click here.

    This OSC protocol is widely used in fields like musical expression, robotics, video performance interfaces, distributed music systems, and inter-process communication. You can use it to drive motors, activate devices, and much more. This example video uses the OSC output to control the direction of rotation of the car.

    Following this tutorial, you will be able to design your own Motor Imagery Classification with your own calibration data and control cars, drones, and devices. Start using BCI technologies to bring products of your imagination to life - there is no limit to what you can imagine!

    - - + + \ No newline at end of file diff --git a/Examples/EMGProjects/EMG_Chrome_Dino_Game/index.html b/Examples/EMGProjects/EMG_Chrome_Dino_Game/index.html index b7c17b7e0..cdc419fe6 100644 --- a/Examples/EMGProjects/EMG_Chrome_Dino_Game/index.html +++ b/Examples/EMGProjects/EMG_Chrome_Dino_Game/index.html @@ -12,13 +12,13 @@ EMG Chrome Dino Game | OpenBCI Documentation - - + +
    Skip to main content

    EMG Chrome Dino Game

    In this tutorial we will show you how to play the Google Chrome Dinosaur Game without touching your laptop. To do that, we will read EMG data from your arm muscles and find the peaks which correspond to flexing, using them to trigger a jump of the dinosaur.

    Check out an example video of this tutorial being put into action!

    EMGdinogif

    The following instructions have been written for use with Linux 16.04.

    Materials Required

    1. OpenBCI Cyton Board
    2. Skintact sticky electrodes or IDUN Dryodes
    3. EMG/ECG Snap Electrode Cables
    4. Computer with downloaded OpenBCI GUI

    Step 1: Hardware Assembly.

    Follow the EMG Getting Started tutorial on this link to connect the electrodes to your body and the Cyton board, and read data from it using the OpenBCI GUI. For this tutorial, you will need to connect one of your arms to Channel 1 and Ground.

    Step 2: Software Setup.

    Install Python version 2 or 3. Here is a useful tutorial to find out if Python is already installed on your computer and to install it. To use this program, you need the following Python packages installed:

    • pylsl : use pip install pylsl from the command line to install it.
    • pyautogui : use pip install pyautogui to install it.
    • brainflow: use pip install brainflow.
    • numpy: use pip install numpy.

    Step 3: Download and Run the Script.

    The Python script will set up the Cyton board, read data from it, and analyze it to detect any spikes that correspond to muscle flexing. If a flex is detected and 100 milliseconds have passed since the last one, it will press the space bar, which will make the dinosaur jump. The threshold for the time between flexes can be modified as needed to avoid debouncing.

    In this tutorial, we provide two alternative ways of processing the data to detect the peaks and encourage you to think of your own ways to do it. Get either the chrome_dino_v1.py or the chrome_dino_v2.py Python script from here by cloning the repository or copying the individual code file to a .py script. Once your board is connected, open a terminal and launch the script by running python <script name> --serial-port /dev/ttyUSB0 --board-id 0 from the folder its stored in.

    Important: If you are using a serial port other than /dev/ttyUSB0, replace it in the above command.

    Once the script has launched, follow the instructions on the terminal. The script chrome_dino_v1.py removes the noise from the signal, squares it, and sets a threshold to detect the peaks. The script chrome_dino_v2.py denoises the signal and then uses a rolling window with normalization to detect the peaks.

    Important: If you are using chrome_dino_v1.py and the mean value printed out is negative, swap the N and P electrode cables and repeat calibration to get a positive mean.

    Next, open a Google Chrome tab and go to the url chrome://dino. You do not have to disable your internet to access this free game. Start the game by pressing the spacebar or flexing your arm. Every time you flex, the dinosaur will jump. Since weโ€™re processing raw signals, the threshold might need to be adjusted. If the jump is not getting triggered, play with the value of flex_thres by modifying the variable directly in chrome_dino_v2.py or the percentage multiplier set to 0.5 in chrome_dino_v1.py. You can also modify the time between flexes by changing the parameter time_thres.

    To learn more about brainflow visit its GitHub repository and its Documentation.

    This is a great example to get started with brainflow. Try it out and send us a video of how you modify this prototype!

    Note:ย Thisย tutorialย isย basedย onย Brainflowย 2020. Ifย youย experienceย anyย issuesย withย theย latestย versionsย emailย usย atย contact@openbci.com.

    - - + + \ No newline at end of file diff --git a/Examples/EMGProjects/EMG_LED/index.html b/Examples/EMGProjects/EMG_LED/index.html index bb9f5207e..6fd390682 100644 --- a/Examples/EMGProjects/EMG_LED/index.html +++ b/Examples/EMGProjects/EMG_LED/index.html @@ -12,14 +12,14 @@ EMG-controlled LED | OpenBCI Documentation - - + +
    Skip to main content

    EMG-controlled LED

    This tutorial is little more involved than the other EMG tutorials. No fear, we've documented every step below. Happy bio-hacking!

    In this tutorial, we will show you how to change the color of an LED depending on your facial expression. To do that, we will read the peaks in EMG signals your face muscles produce when you flex them and use them to change the color of an LED. The yellow color will indicate smiling, the red color frowning, and the blue color a neutral expression.

    Check out the example video of this tutorial being put into action!

    EMG_LED_gif

    The following instructions have been written for use with Windows 10.

    Materials Required

    Step 1: Hardware Assembly

    For this project you will need five gold cup electrodes. Connect the first electrode cable to the bottom AGND pin, and the other four electrode cables to the top and bottom pins of Channel 1 (N1P) and Channel 2 (N2P), as shown on the picture below.

    Now itโ€™s time to connect the electrodes to your body. To connect a gold cup electrode to your skip, apply some Ten20 paste on it like shown on the picture below, and stick it to your skin. To secure the connection, you can put some medical tape over it.

    Now connect the five electrodes as shown on the picture below. The two electrodes on top of your eyebrow go to top and bottom N2P pins on the Cyton, the two electrodes closest to your mouth go to top and bottom N1P pins, and the electrode closest to your ear goes to bottom AGND. You can also use the color of the wires as a guide to know which electrode goes where.


    Electrode Wire ColorCyton Board PinBody LocationPurpose
    greybottom AGND pinon face, close to earreference
    purpletop N1P pincorner of mouthmeasuring potential difference on channel 1
    whitebottom N1P pinmiddle of cheekmeasuring potential difference on channel 1
    greentop N2P pinouter browmeasuring potential difference on channel 2
    bluebottom N2P pininner browmeasuring potential difference on channel 2


    To assemble the circuit for the LEDs and Arduino, the first step is to connect the LEDs to the Arduino for each color. The connections are shown on the diagram below. For each color, yellow, red and blue, the Collector pin of the transistor (top connection in the diagram below) needs to be connected to 5 volts either through the USB pin or the 5V pin of the Arduino. Next, the Base of the transistor (middle pin in the diagram) gets connected to the Arduino GPIO pin of choice. In this case, we will use pin 12 for red, pin 11 for blue and pin 8 for yellow.

    Finally, the LED gets connected to the Emitter pin of the transistor and to the Arduino pin GND through a resistor. In this way, the transistor acts as a switch to turn ON/OFF the group of LEDs while protecting the Arduino pin from receiving too much current.

    The diagram above needs to be replicated for every color, with as many LEDs as you like. An example breadboard set-up is shown below.

    Step 2: Arduino Setup

    The first step is to download the Arduino IDE from here. Once you have downloaded and installed the Arduino IDE, you should see a screen like the one below.

    Download the folder with the code from here and open it using the Arduino IDE by clicking on File >> Open... and selecting the entire folder. Connect the Arduino to the computer by clicking on Tools, then selecting the right Board and Port options. Next, click on Upload and wait for the code to be uploaded.

    Once the code has been loaded into the Arduino, open the Serial Monitor in the Arduino IDE and try sending the commands โ€˜Yโ€™, โ€˜Gโ€™, and โ€˜Bโ€™ to the Arduino. The LED color should change to Red, Green and Blue respectively if everything is correct. After testing, close the Serial Monitor.

    Important: Donโ€™t proceed to the next step until you have closed it.

    Step 3: Software Setup

    Download and install Python (either version 2 or 3). Python might already be installed on your computer. Type python --version to check if you have Python version 2 or 3 installed. To use this program, you need the following Python packages installed:

    • pylsl: use python -m pip install pylsl from the Python folder in the command line to install it.
    • serial: use python -m pip install serial to install it.

    Step 4: Stream data using the GUI

    Follow the Networking Tutorial to learn how to stream data using LSL from the GUI. For this project, you will need to stream the EMG data from Channels 1 and 2 using the Networking Widget. Your Networking settings should look as follows:

    info

    Important: Make sure your EMG widget is open before you start streaming.

    Step 5: Using a Python Script to Send Data to the Arduino

    The Python script will search for the EMG data streams. Once it finds them it will read it and detect any spikes that correspond to the face muscle flexing. If a flex is detected and 10 milliseconds have passed since the last flex, it will send the corresponding letter โ€˜Rโ€™, โ€˜Yโ€™ or โ€˜Bโ€™ depending on which gesture was detected. The threshold for the time between flexes can be modified as needed to avoid debouncing.

    Get the Python script from here by clicking on โ€˜Rawโ€™ and copying it to a .py file in your Python folder. Once youโ€™re streaming data from the GUI, go to the folder that you stored the script in from your command line, and run it using python.exe <script_name>.py

    Hold the breadboard with LEDs towards your face in a dark environment and check how the color changes when you smile and frown. By modifying the time_thres and flex_thres parameters in the code you can adjust the time to wait between flexes and the flex strength to your needs.

    Try it out and send us a video of your final prototype!

    - - + + \ No newline at end of file diff --git a/Examples/EMGProjects/EMG_Tetris/index.html b/Examples/EMGProjects/EMG_Tetris/index.html index dbd695c10..6ca226409 100644 --- a/Examples/EMGProjects/EMG_Tetris/index.html +++ b/Examples/EMGProjects/EMG_Tetris/index.html @@ -12,13 +12,13 @@ EMG-controlled Tetris | OpenBCI Documentation - - + +
    Skip to main content

    EMG-controlled Tetris

    In this tutorial, we will show you how to make your own muscle-controlled Tetris game. You can now play Tetris on your computer without pressing any keys!

    To do that, we will be using the Cyton's built-in accelerometer to track head movement and EMG signals produced when you blink to rotate the pieces.

    Check out an example video of this tutorial being put into action!

    Tetris Demo Video

    Materials Required

    1. OpenBCI Cyton Board
    2. OpenBCI Ultracortex Mark IV
    3. Computer with downloaded OpenBCI GUI

    Step 1: Hardware Assembly.

    Follow the Ultracortex Mark IV Getting Started tutorial on this link to connect assemble and properly connect the channels on your headset. The linked tutorial will also show you how to connect the Cyton board and stream data to the OpenBCI GUI.

    Step 2: Software Setup.

    Download and install Python (preferrably version 3). Python might already be installed on your computer. Type python --version to check if you have Python version 2 or 3 installed. To use this program, you need the following Python packages installed: pyautogui, socket, sys, time, argparse, signal, json.

    Step 3: Data Stream using the GUI.

    For this project, you will be streaming data using UDP through the GUI from the Networking Widget. Open up the Accelerometer, EMG, and Networking widgets and configure the networking widget to look like below:

    EMG Tetris GUI UDP Screenshot

    Mainly, change the protocol from Serial to UDP and set the Data Type of Stream 1 and 2 as Accel/Aux and EMG respectively. Furthermore, change the Port of both Stream 1 and 2 to โ€œ12345โ€. Before continuing, ensure the electrodes are making good contact with the scalp by examining the noise in the timeseries widget. Proper data is essential for clean readings and control of the Tetris game.

    info

    Important:ย Make sure your EMG and Accelerometer widgets are open before you start streaming.

    Step 4: Using a Python Script to Read the Data and Scroll.

    The Python script will search for the EMG and Accelerometer data streams. Once it finds them, it will read them and detect any spikes that correspond to blinks as well as movements of the head.

    info

    Download the Python script from here.

    Run the Python script in your preferred IDE or through your command line using "python tetris.py" in the directory where you have it saved. Once you run the script, you can start the data stream and start the UDP stream from the GUI data.

    Keep your head still for the less than 10 second calibration period. Once the calibration period is complete (indicated by the "Calibration done. You may now begin Tetris!" message), go ahead and navigate to your favorite online Tetris website with arrow and space controls (these controls can be modified using the variables at the start of the code).

    note

    We recommend using https://jstris.jezevec10.com.

    Try it out and send us a video of your final prototype!

    - - + + \ No newline at end of file diff --git a/Examples/EMGProjects/EMGmusic/index.html b/Examples/EMGProjects/EMGmusic/index.html index 6b203dc0f..e5b2cc01e 100644 --- a/Examples/EMGProjects/EMGmusic/index.html +++ b/Examples/EMGProjects/EMGmusic/index.html @@ -12,13 +12,13 @@ EMG-controlled Music | OpenBCI Documentation - - + +
    Skip to main content

    EMG-controlled Music

    In this tutorial, we will show you how to pause and unpause your music without pressing any keys on your laptop keyboard. To do that, we will read the peaks in EMG signals your arm muscles produce when you flex them and use them as a trigger for pausing the music played via Youtube through your computer. Feel free to connect your laptop to a Bluetooth speaker to make the music louder!

    Check out an example video of this tutorial being put into action!

    EMGmusicgif

    The following instructions have been written for use with Windows 10.

    Materials Required

    1. OpenBCI Cyton Board
    2. Skintact sticky electrodes or IDUN Dryode
    3. EMG/ECG Snap Electrode Cables
    4. Computer with downloaded OpenBCI GUI

    Step 1: Hardware Assembly.

    Follow the EMG Getting Started Tutorial to connect the electrodes to your body and the Cyton board, and read data from it using the OpenBCI GUI.

    Step 2: Software Setup.

    Download and install Python (either version 2 or 3). Python might already be installed on your computer. Type python --version to check if you have Python version 2 or 3 installed. To use this program, you need the following Python packages installed:

    • pylsl: use python -m pip install pylsl from the Python folder in the command line to install it.
    • pyautogui : use python -m pip install pyautogui to install.

    Step 3: Stream data using the OpenBCI GUI.

    Follow the networking tutorial on this link to learn how to stream data using LSL from the GUI. For this project, you will need to stream the EMG data from Channel 1 using the Networking Widget. Your Networking settings should look as follows:

    info

    Important: Make sure your EMG widget is open before you start streaming.

    Step 4: Using a Python Script to Read the Data and Execute EMG Command

    The Python script will search for an EMG data stream. Once it finds the stream it will read it and detect any spikes that correspond to muscle flexing. If a flex is detected and 2 seconds have passed since the last one, it will press the space bar, which will make the music stop. The threshold for the time between flexes can be modified as needed to avoid debouncing.

    Get the Python script from here by clicking on โ€˜Rawโ€™ and copying it to a .py file in your Python folder. Once youโ€™re streaming data from the GUI, go to the folder that you stored the script in from your command line, and run it using python.exe <script_name>.py.

    Open Youtube and play some music. Every time you flex your arm as shown in the example video, the music will pause or start playing if paused already. By modifying the time_thres and flex_thres parameters in the code you can adjust the time to wait between flexes and the flex strength to your needs.

    Try it out and send us a video of your final prototype!

    - - + + \ No newline at end of file diff --git a/Examples/EMGProjects/EMGpiano/index.html b/Examples/EMGProjects/EMGpiano/index.html index 43953269e..952e97eb7 100644 --- a/Examples/EMGProjects/EMGpiano/index.html +++ b/Examples/EMGProjects/EMGpiano/index.html @@ -12,13 +12,13 @@ EMG-controlled Piano | OpenBCI Documentation - - + +
    Skip to main content

    EMG-controlled Piano

    In this tutorial, we will show you how to play the piano using just the EMG signals from your fingers! To do that, we will read EMG data from the muscles joining your fingers to your arms and find the peaks which correspond to pressing a key on a piano, using them as a trigger to play a virtual keyboard.

    Check out an example video of this tutorial being put into action!

    EMG Piano Tutorial

    Materials Required

    1. OpenBCI Cyton Board
    2. Skintact sticky electrodes or IDUN Dryode
    3. EMG/ECG Snap Electrode Cables
    4. Computer with downloaded OpenBCI GUI

    Step 1: Hardware Assembly

    Follow the EMG Getting Started tutorial on this link to connect the electrodes to your body and the Cyton board, and read data from it using the OpenBCI GUI. For this tutorial, 4 channels are used: Channel 1 = right pinky, Channel 2 = right pointer, Channel 3 = left pointer, Channel 4 = left pinky. Only one ground is needed.

    Important: The most complicated part of this tutorial can be finding the right placement for each set of electrodes. The diagram seen below should work well universally, but feel free to mess around with the placement a bit to find where the most prominent flexes occur along your arms.

    Electrode Placement Diagram

    Step 2: Software Setup

    Download and install Python (either version 2 or 3). Python might already be installed on your computer. Type python --version to check if you have Python version 2 or 3 installed. To use this program, you need the following Python packages installed:

    • pylsl: use python -m pip install pylsl from the Python folder in the command line to install it.
    • pyautogui : use python -m pip install pyautogui to install.

    Step 3: Stream data using the OpenBCI GUI

    Follow the networking tutorial on this link to learn how to stream data using LSL from the GUI. For this project, you will need to stream the EMG data from Channels 1-4 using the Networking Widget. Your Networking settings should look as follows:

    LSL Networking Widget Screenshot

    Important: Make sure your EMG widget is open before you start streaming.

    Step 4: Using a Python Script to Read the Data and Play

    The Python script will search for an EMG data stream. Once it finds the stream it will read it and detect any spikes that correspond to finger flex. If a flex is detected and 1 second has passed since the last flex, it will press a certain key, which will play a certain note on a virtual keyboard. The threshold for the time between flexes can be modified as needed to avoid debouncing.

    Get the Python script from here by clicking on โ€˜Rawโ€™ and copying it to a .py file in your Python folder. Once youโ€™re streaming data from the GUI, go to the Python folder from your command line by using the cd command, and run it using python <script_name>.py

    Open a virtual keyboard; we used this one. Every time you move one of your fingers, it will play certain notes. By modifying the time_thres, pointer_thres, and pinky_thres parameters in the code, you can adjust the time to wait between finger movements and the strength of each movement to your needs.

    Note: The pointer finger flex can be slightly weaker, so the script establishes separate thresholds for the pointer fingers and the pinkies.

    The script codes for 4 different notes to play, each designated to one finger: G4 = right pinky, E4 = right pointer, D4 = left pointer, C4 = left pinky. To play Mary Had a Little Lamb, use the following guide in terms of Channels:

    2 , 3 , 4 , 3 , 2 , 2 , 2 , 3 , 3 , 3 , 2 , 1 , 1 , 2 , 3 , 4 , 3 , 2 , 2 , 2 , 2 , 3 , 3 , 2 , 3 , 4

    Try it out and send us a video of your final prototype!

    - - + + \ No newline at end of file diff --git a/Examples/EMGProjects/EMGscrolling/index.html b/Examples/EMGProjects/EMGscrolling/index.html index 1c067f874..94682b9ab 100644 --- a/Examples/EMGProjects/EMGscrolling/index.html +++ b/Examples/EMGProjects/EMGscrolling/index.html @@ -12,13 +12,13 @@ EMG Scrolling | OpenBCI Documentation - - + +
    Skip to main content

    EMG Scrolling

    In this tutorial, we will show you how to scroll up and down on your computer screen without touching the keyboard. For that, we will read the peaks in EMG signals your arm muscles produce when you flex them and use them to scroll.

    Check out an example video of this tutorial being put into action!

    EMGscrollgif

    The following instructions have been written for use with Windows 10.

    Materials Required

    1. OpenBCI Cyton Board
    2. Skintact sticky electrodes or IDUN Dryode
    3. EMG/ECG Snap Electrode Cables
    4. Computer with downloaded OpenBCI GUI

    Step 1: Hardware Assembly.

    Follow the EMG Getting Started tutorial on this link to connect the electrodes to your body and the Cyton board, and read data from it using the OpenBCI GUI. For this tutorial, you will need to connect both arms, one to Channel 1 and the other one to Channel 2. Only one ground is needed.

    Step 2: Software Setup.

    Download and install Python (either version 2 or 3). Python might already be installed on your computer. Type python --version to check if you have Python version 2 or 3 installed. To use this program, you need the following Python packages installed:

    • pylsl : use python -m pip install pylsl from the Python folder in the command line to install it.
    • pyautogui : use python -m pip install pyautogui to install it.

    Step 3: Data Stream using the GUI.

    Follow the networking tutorial to learn how to stream data using LSL from the GUI. For this project, you will need to stream the EMG data using the Networking Widget. Your Networking settings should look as follows:

    info

    Important: Make sure your EMG widget is open before you start streaming.

    Step 4: Using a Python Script to Read the Data and Scroll.

    The Python script will search for the EMG data streams. Once it finds them it will read the and detect any spikes that correspond to the muscle contractions. If a flex is detected and 10 milliseconds have passed since the last one, it will scroll up or down depending on which arm was flexed. The threshold for the time between flexes can be modified as needed to avoid debouncing.

    Download the Python script from here by clicking on โ€˜Rawโ€™ and copying it to a .py file in your Python folder. Once youโ€™re streaming data from the GUI, go to the folder that you stored the script in from your command line, and run it using python.exe <script_name>.py

    Open one of your favourite websites in your browser and scroll through it flexing your arms. By modifying the time_thres and flex_thres parameters in the code, you can adjust the time to wait between flexes and the flex strength to your needs.

    Try it out and send us a video of your final prototype!

    - - + + \ No newline at end of file diff --git a/Examples/EMGProjects/EMGslideshow/index.html b/Examples/EMGProjects/EMGslideshow/index.html index 043fa1d33..1b006ed42 100644 --- a/Examples/EMGProjects/EMGslideshow/index.html +++ b/Examples/EMGProjects/EMGslideshow/index.html @@ -12,13 +12,13 @@ EMG-controlled Slideshow | OpenBCI Documentation - - + +
    Skip to main content

    EMG-controlled Slideshow

    In this tutorial, we will show you how to scroll through a presentation using your eyes. To do that, we will read EMG data from the muscles around your eyes and find the peaks which correspond to blinking, using them as a trigger to scroll to the next slide. Even though we are using eye blinks in this example, any EMG signals such as those produced by your jaw when you clench it or your arms when you move them can be used.

    Check out an example video of this tutorial being put into action!

    EMGslideshowgif

    The following instructions have been written for use with Windows 10.

    Materials Required

    1. OpenBCI Cyton Board
    2. EEG Headband Kit
    3. Computer with downloaded OpenBCI GUI

    Step 1: Hardware Assembly

    Follow the tutorial to assemble the EEG Headband Kit, connect it to the Cyton Board, and read data from it using the OpenBCI GUI.

    Important: For this project, using a single channel is enough. When following the tutorials in the link above, you only need to connect the electrode on top of the eye you will be blinking (any eye if you will blink both) to Channel 1.

    Step 2: Software Setup

    Download and install Python (either version 2 or 3). Python might already be installed on your computer. Type python --version to check if you have Python version 2 or 3 installed. To use this program, you need the following Python packages installed:

    • pylsl: use python -m pip install pylsl from the Python folder in the command line to install it.
    • pyautogui : use python -m pip install pyautogui to install.

    Step 3: Stream data using the OpenBCI GUI

    Follow the networking tutorial on this link to learn how to stream data using LSL from the GUI. For this project, you will need to stream the EMG data from Channel 1 using the Networking Widget. Your Networking settings should look as follows:

    info

    Important: Make sure your EMG widget is open before you start streaming.

    Step 4: Using a Python Script to Read the Data

    The Python script will search for an EMG data stream. Once it finds the stream it will read it and detect any spikes that correspond to eye blinks. If an eye blink is detected and 2 seconds have passed since the last eye blink, it will press the space bar, which will make the presentation go to the next slide. The threshold for the time between blinks can be modified as needed to avoid debouncing.

    Get the Python script from here by clicking on โ€˜Rawโ€™ and copying it to a .py file in your Python folder. Once youโ€™re streaming data from the GUI, go to the Python folder from your command line by using the cd command, and run it using python.exe <script_name>.py

    Open your slideshow in Presentation mode. Every time you blink, it will go to the next slide. By modifying the time_thres and blink_thres parameters in the code you can adjust the time to wait between binks and the blink strength to your needs.

    Try it out and send us a video of your final prototype!

    - - + + \ No newline at end of file diff --git a/Examples/ExamplesLanding/index.html b/Examples/ExamplesLanding/index.html index a385e1156..7f8f87101 100644 --- a/Examples/ExamplesLanding/index.html +++ b/Examples/ExamplesLanding/index.html @@ -12,13 +12,13 @@ Example Projects | OpenBCI Documentation - - + +
    Skip to main content

    Example Projects

    The Examples directory to the left contains example projects contributed by members of the OpenBCI Community and team. For even more tutorials, head to the tutorials tag in the Community Page!

    EEG Projects and Tutorials

    Whether you're new to neurotechnology or conducting research, OpenBCI makes it easy and fun to work with EEG signals. OpenBCI hardware can be used to replicate and expand upon existing EEG paradigms. Below, you will find a few examples from our worldwide Community of scientists and enthusiasts to help you get started controlling computers and robots using the power of your mind.

    P300 Example

    P300 Speller by UCLA - Uses Cyton and Gel Electrode Cap

    SSVEP Examples

    SSVEP-based BCI speller by McGill University - Uses Cyton and Gold Cup Electrodes

    SSVEP-based communicator by University of Waterloo - Uses Cyton + Customized Ultracortex

    Motor Imagery Controlled Car

    Tutorial to control a robotic car using motor imagery - Uses Cyton Board and Ultracortex EEG headset or EEG cap

    EMG Projects and Tutorials

    We added all-newย tutorials for facial, ocular, and limbย EMG, as well as expanded our ECG and stand-alone EMG tutorials! OpenBCI documentation is meant to be an actionable jumping-off point for your BCI and bio-sensing exploration.ย  We look forward to seeing what you create!

    Note, the example projects below are written for the Cyton Board but can be applied to Ganglion board as well.

    EMG Scrolling

    Tutorial for touch-less scrolling with limb EMG

    EMG-controlled Stop/Start Music

    Tutorial for limb EMG-triggered music playback

    EMG-controlled Slideshow

    Tutorial for eye, facial, or arm EMG-controlled slideshow

    EMG-controlled LED

    Tutorial for facial EMG-controlled LEDs

    EMG-controlled Chrome Browser Dinosaur Game

    Tutorial how to play the Google Chrome Dinosaur Game without touching your laptop, using arm EMG

    EMG-controlled Tetris Game

    Tutorial to play Tetris using EMG and an OpenBCI board's built-in Accelerometer

    EMG-controlled Piano

    Tutorial to play the piano using EMG

    - - + + \ No newline at end of file diff --git a/Examples/VideoExperiment/index.html b/Examples/VideoExperiment/index.html index c13d805bd..15c70b94b 100644 --- a/Examples/VideoExperiment/index.html +++ b/Examples/VideoExperiment/index.html @@ -12,13 +12,13 @@ Puppies and Kittens Experiment | OpenBCI Documentation - - + +
    Skip to main content

    OpenBCI Experiment

    Welcome to the OpenBCI Puppies and Kittens Experiment designed by Fan Li.

    During this experiment, you will watch a video containing images of puppies and kittens, and press a button every time you see a puppy in the image.

    Below are the instructions on how to do it. The full information on this experiment can be found on the OpenBCI Repository. Once you're comfortable with how the experiment works, you can modify the script to create your own experiments.

    Equipment Required

    1. Headwear, which can be:

    2. Cyton Board

    3. OpenBCI GUI

    4. Breadboard. The breadboard includes a photocell circuit for the trigger and a button circuit for user feedback. The components needed for both are:

    Step 1: Headwear, Board and Software Setup

    First, connect the headwear to yourself and the Cyton board, and read from it using the GUI. If you are using the Ultracortex, follow this tutorial. If you're using the gold cup electrodes, follow this guide to learn how to connect each electrode, and connect them in the positions you would like to measure EEG from. A good guide to the 8 positions commonly used can be found in the Ultracortex tutorial. If you're using an electrode cap, follow this tutorial to connect it.

    Step 2: Breadboard Setup

    The diagram for the circuit with the photocell and the button can be found below.

    Using the components listed above, assemble the breadboard. You can find an example of how to assemble a button circuit using Arduino here and an example of how to assemble a photocell circuit here. The final breadboard should look similar to the pictures.

    Next, connect the breadboard to the Cyton board as shown below. Place the breadboard beside your computer such that the photocell points to the lower-left corner of your screen, which is where the video trigger will be located.

    Step 4: Run Experiment

    Download this video. Once you're ready to start, press Start Data Stream in the GUI. Then, open the video and make it Full-Screen. Every time a puppy appears in the video, press the button. The video is around 3 minutes long. You're now ready to press play!

    Step 5: Retrieve Data

    Once you've finished watching the video, press Stop Data Stream. In your /Documents/OpenBCI_GUI/Recordings folder you should find the recorded data for that session.

    Step 6: Process Data

    In this Python notebook, you'll find sample code to read, plot, and analyze the recorded data.

    Step 7: Create your Own Experiment

    Once you understand how to conduct an experiment, you can modify this Python script to make your own video. The current code reads the images stored in the Images folder, shuffles them, and creates a video with 4 different sessions. Each session displays the images at a different rate. Each image has an embedded trigger and is separated from the others by a fixation cross.

    The video pattern was created in accordance to the diagram below obtained from the research paper Toward Emotion Aware Computing: An Integrated Approach Using Multichannel Neurophysiological Recordings and Affective Visual Stimuli by C. A. Frantzidis, C. Bratsas, C. L. Papadelis, E. Konstantinidis, C. Pappas and P. D. Bamidis, published in IEEE Transactions on Information Technology in Biomedicine, vol. 14, no. 3, pp. 589-597, May 2010.

    - - + + \ No newline at end of file diff --git a/FAQ/Conduct/index.html b/FAQ/Conduct/index.html new file mode 100644 index 000000000..37e003846 --- /dev/null +++ b/FAQ/Conduct/index.html @@ -0,0 +1,34 @@ + + + + + + + + + + + + + +Code of Conduct | OpenBCI Documentation + + + + +
    +
    Skip to main content

    Code of Conduct

    Our Pledge

    In the interest of fostering an open and welcoming environment, we hope to provide a safe, welcoming, and warmly geeky environment for everybody, regardless of gender, sexual orientation, disability, ethnicity, socioeconomic status, and religion (or lack thereof).

    Our Standards

    Examples of behavior that contributes to creating a positive environment +include:

    • Using welcoming and inclusive language
    • Being respectful of differing viewpoints and experiences
    • Gracefully accepting constructive criticism
    • Focusing on what is best for the community
    • Showing empathy towards other community members

    Examples of unacceptable behavior by participants include:

    • The use of sexualized language or imagery and unwelcome sexual attention or +advances
    • Trolling, insulting/derogatory comments, and personal or political attacks
    • Public or private harassment
    • Publishing others' private information, such as a physical or electronic +address, without explicit permission
    • Other conduct which could reasonably be considered inappropriate in a +professional setting

    Enforcement

    Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the team at contact@openbci.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately.

    This Code of Conduct applies within all OpenBCI spaces.

    Attribution

    This Code of Conduct is adapted from the Contributor Covenant, version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

    + + + + \ No newline at end of file diff --git a/FAQ/Cookie/index.html b/FAQ/Cookie/index.html index 2dbf3f532..874b4086d 100644 --- a/FAQ/Cookie/index.html +++ b/FAQ/Cookie/index.html @@ -12,19 +12,19 @@ OpenBCI Cookie Policy | OpenBCI Documentation - - + +
    -
    Skip to main content

    OpenBCI Cookie Policy

    What Are Cookies

    As is common practice with almost all professional websites this site uses cookies, which are tiny files that are downloaded to your computer, to improve your experience. This page describes what information they gather, how we use it and why we sometimes need to store these cookies. We will also share how you can prevent these cookies from being stored however this may downgrade or 'break' certain elements of the sites functionality. +

    OpenBCI Cookie Policy

    What Are Cookies

    As is common practice with almost all professional websites this site uses cookies, which are tiny files that are downloaded to your computer, to improve your experience. This page describes what information they gather, how we use it and why we sometimes need to store these cookies. We will also share how you can prevent these cookies from being stored however this may downgrade or 'break' certain elements of the sites functionality. For more general information on cookies see the Wikipedia article on HTTP Cookies.

    How We Use Cookies

    We use cookies on our site, store and community pages in a number of ways in order to:

    1. Understand and save user's preferences for future visits.
    2. Keep users logged into community and forum pages.
    3. Help remember and process the items in the shopping cart.
    4. Identify users for targeting of OpenBCI marketing efforts on other websites (search, social and display advertisements)
    5. Compile aggregate data about site traffic and site interactions in order to offer better site experiences and tools in the future.

    We may also use trusted third-party services that track this information on our behalf.

    Disabling Cookies

    You can prevent the setting of cookies by adjusting the settings on your browser (your browser will have specific documentation for how to do this). Unfortunately is most cases there are no industry standard options for disabling cookies without completely disabling the functionality and features they add to this site. Be aware that disabling cookies will affect the functionality of this and many other websites that you visit. Disabling cookies will usually result in also disabling certain functionality and features of the this site.

    The Cookies We Set

    In order to provide you with a great experience on this site we provide the functionality to set your preferences for how this site runs when you use it. In order to remember your preferences we need to set cookies so that this information can be called whenever you interact with a page is affected by your preferences. We use cookies when you are logged in so that we can remember this fact. This prevents you from having to log in every single time you visit a new page. These cookies are typically removed or cleared when you log out to ensure that you can only access restricted features and areas when logged in. This site offers e-commerce or payment facilities through Shopify and some cookies are essential to ensure that your order is remembered between pages so that we can process it properly. More detail on Shopify cookies can be found in the Shopify cookie policy.

    Third Party Cookies

    In some special cases we also use cookies provided by trusted third parties. The following section details which third party cookies you might encounter through this site. This site uses Google Analytics which is one of the most widespread and trusted analytics solution on the web for helping us to understand how you use the site and ways that we can improve your experience. These cookies may track things such as how long you spend on the site and the pages that you visit so we can continue to produce engaging content. For more information on Google Analytics cookies, see the official Google Analytics page. We also use social media buttons and/or plugins on this site that allow you to connect with your social network in various ways. For these to work the following social media sites including; Facebook, Twitter, Google+, will set cookies through our site which may be used to enhance your profile on their site or contribute to the data they hold for various purposes outlined in their respective privacy policies.

    Additional Advertising Technology Partners

    This site may use targeting and advertising technologies such as web beacons and pixel tags to deliver relevant advertisements. These technologies collect information about your browsing habits across our site and how you use our services. Our advertising partners may use the information as outlined in their respective privacy policies. We currently use the following partners: (i) Facebook; (ii) Shopify; (iii) Google; and (iv) Twitter. For information on opting out of tracking, please refer to each partnersโ€™ privacy policy, or the Digital Advertising Allianceโ€™s WebChoices tool. Opting out of partner tracking will prevent OpenBCIโ€™s ability to deliver you customized, relevant advertising.

    More Information

    Hopefully that has clarified things for you and as was previously mentioned if there is something that you aren't sure whether you need or not it's usually safer to leave cookies enabled in case it does interact with one of the features you use on our site. However if you are still looking for more information you can contact us at contact@openbci.com

    - - + + \ No newline at end of file diff --git a/FAQ/DocsUpdate/index.html b/FAQ/DocsUpdate/index.html index 939db87ba..d69b01266 100644 --- a/FAQ/DocsUpdate/index.html +++ b/FAQ/DocsUpdate/index.html @@ -12,13 +12,13 @@ Docs Website Update | OpenBCI Documentation - - + +

    Docs Website Update

    We have recently updated the Docs website! You may be seeing this page if you have attempted to access a page that has moved. You can find the same information using either the dropdowns on the left or the "Search Docs" function in the top right of this window. Enjoy!

    - - + + \ No newline at end of file diff --git a/FAQ/FAQLanding/index.html b/FAQ/FAQLanding/index.html index 6fac1877a..9e8066143 100644 --- a/FAQ/FAQLanding/index.html +++ b/FAQ/FAQLanding/index.html @@ -12,13 +12,13 @@ Frequently Asked Questions | OpenBCI Documentation - - + +

    Frequently Asked Questions

    Welcome to our Frequently Asked Questions (FAQ)! Select the appropriate question category to proceed:

    Our open-source, low-cost, and research-grade hardware lowers the cost to entry. By creating these biosensing tools, we enable lower-budget institutions, academic researchers, DIY scientists, and a global population of makers to participate in this emerging field.

    Head to our searchable Citation List, a regularly updated collection of independent research published using OpenBCI!

    - - + + \ No newline at end of file diff --git a/FAQ/GenFAQ/index.html b/FAQ/GenFAQ/index.html index a966b0ab1..cbf717144 100644 --- a/FAQ/GenFAQ/index.html +++ b/FAQ/GenFAQ/index.html @@ -12,13 +12,13 @@ General Frequently Asked Questions | OpenBCI Documentation - - + +

    General Frequently Asked Questions

    What does OpenBCI stand for?

    Open Brain Computer Interface. We believe that science advancements will onlyโ€”and should onlyโ€”be made through an open forum of shared knowledge and concerted effort, by people from a variety of backgrounds. We work to harness the power of the open source movement to accelerate ethical innovation of human-computer interface technologies.

    Where can I find what people have been doing with OpenBCI?

    People working with OpenBCI regularly post about their projects on our Community Page.

    See our weekly-updated searchable Citation List, a collection of innovative OpenBCI-based research.

    We've been featured in publications such as Nature!

    I have a technical question. Who should I contact?

    For technical questions please use our Forum, we maintain them regularly and we will get back to you.

    Do you offer consulting or guided research for projects?

    At the moment we do not offer guided research or consulting opportunities.

    How do I become an approved OpenBCI Affiliate or Reseller?

    Please email us at contact@openbci.com asking for our affiliate program!

    How can I contact OpenBCI if I have more questions?

    You can email us at contact@openbci.com

    - - + + \ No newline at end of file diff --git a/FAQ/HardFAQ/index.html b/FAQ/HardFAQ/index.html index 156e2dbcf..fde4505b8 100644 --- a/FAQ/HardFAQ/index.html +++ b/FAQ/HardFAQ/index.html @@ -12,15 +12,15 @@ Hardware & Software | OpenBCI Documentation - - + +

    Hardware & Software

    What do I need to get started?

    To get started, all you need is an OpenBCI Board (Ganglion or Cyton), some electrodes, and a computer! Note that you do not need an Ultracortex. In fact, you can use any standard EEG electrode cap with the OpenBCI Boards.

    Can I use OpenBCI with other hardware & software?

    Yes! OpenBCI is designed to be easily interfaced by other hardware and software. The OpenBCI hardware is software agnostic, meaning it works with OpenBCI-specific software, as well as any other 3rd-Party Software that has an OpenBCI driver. Check out the Tutorials Section to find guides that detail connecting OpenBCI to other tools.

    What is the difference between the Ganglion, the Cyton Board, and the Cyton + Daisy Boards?

    The Cyton Board is an 8 channel bio-sensing amplifier that can measure ECG, EMG, and EEG. It connects to your computer wirelessly with an included USB Dongle. Data is sampled at 250Hz. The Cyton + Daisy is the same as the Cyton Board, but it also includes an expansion module to increase the channel count to 16. Data is sampled at 125Hz. The Ganglion is a 4 channel bio-sensing amplifier that can measure ECG, EMG, and EEG. It connects to your computer via BLE. Data is sampled at 200Hz.

    The boards sample rate is limited by the bluetooth bandwidth. In order to increase the sample rate, you can purchase the WiFi Shield. The WiFi Shield increases the sample rate by transmitting the data via WiFi as opposed to Bluetooth. The WiFi Shield can be controlled through HTTP requests and can send JSON objects with data in nano volts.

    With the WiFi Shield connected:

    • The Cyton can stream data at 50Hz, 500Hz, 1000Hz, 2000Hz.
    • The Cyton + Daisy can to stream data at 250Hz, 500Hz, 1000Hz.
    • The Ganglion can stream data at 200Hz, 400Hz, 800Hz, 1600Hz.

    How do I choose between 4, 8, or 16 channels for my research?

    With additional channels, you have additional spatial resolution. The Ganglion (the 4-channel board) is great for low-cost research and education. The Cyton (8-16 channels) provides additional spatial resolution, enabling more diverse types of research requiring higher channel counts.

    Where do I download the OpenBCI software?

    You can go to our downloads page!

    - - + + \ No newline at end of file diff --git a/FAQ/HowProductsGoTogether/index.html b/FAQ/HowProductsGoTogether/index.html index be976fba9..cef868e13 100644 --- a/FAQ/HowProductsGoTogether/index.html +++ b/FAQ/HowProductsGoTogether/index.html @@ -12,13 +12,13 @@ How OpenBCI products go together? | OpenBCI Documentation - - + +

    How OpenBCI products go together?

    image

    What products should I get?

    If you are new to OpenBCI or you are just curious about our products donโ€™t fret! Watch our tutorial of How OpenBCI Products Go Together to get a crash course on your first set-up!

    Here is a detailed explanation of what you need to get started:

    The first component you would need is one of our 3 Biosensing Boards. You will select a board depending on how many electrodes you want to analyze data from. In general, with additional channels, you have additional spatial resolution that enables more diverse types of research. We offer three different boards, the Ganglion Board (4 channels at a sample rate of 200Hz), the Cyton Board (8 channels at a sample rate of 250Hz), and the Cyton + Daisy Boards (16 channels at a sample rate of 125Hz). Each channel lets you plug one electrode into them, so the more channels you have the more electrodes you can play with. If you are purchasing the Ganglion board you will need the Ganglion Dongle.

    The boards sample rate is limited by the bluetooth bandwidth.

    Now that you have the board, the second thing you need to get started is a set of electrodes (or a headset, weโ€™ll talk about it after). Our Boards have male header connectors, so you would need to get electrodes that are compatible. If you are interested in mainly doing EMG or ECG, we recommend you use our EMG/ECG Snap Electrode Cables with EMG/ECG Foam Solid Gel Electrodes (30/pack), these electrodes are a ready to go solution and plug in directly into our Biosensing boards. If you want to be able to do EEG as well as EMG and ECG, we recommend you get our Gold Cup Electrodes with Ten 20 Paste. You can affix these electrodes (almost) everywhere with some medical tape, which allows you to measure EEG, EMG, and ECG. If you already have your own electrodes, or have an electrode cap with touch proof connectors, you can still use them with our Biosensing Boards, by purchasing our Header Pin to Touch Proof Electrode Adapter.

    Another way to go is to purchase the Mark IV headset. At its core the Mark IV is a frame with dry electrodes, that allows you to affix the dry electrodes to the scalp without having to use any paste. If you are mainly interested in EEG and do not want to have to go through the hassle of using EEG Paste on your hair, this is the way to go. You can purchase the Mark IV with either 8 electrodes or 16 electrodes (you donโ€™t need to purchase extra electrodes). The Mark IV comes in 3 configurations, Print it Yourself, Unassembled, and Pro-Assembled. The Print it Yourself version is great if you have a 3D printer and you are able to print some of the parts yourself. The Print it Yourself version includes all of the electrodes, cables, and all of the other parts that arenโ€™t 3D printable. The Unassembled version comes with all the necessary materials to build the headset, sort of like a puzzle but easier. You can check the assembly guide for instructions. If you donโ€™t want to bother with assembly or 3D printing parts, you can buy an already assembled headset, our Pro-Assembled Mark IV. Note that neither headset comes with a Biosensing board.

    We recommend that if you are getting the 8 Channel Mark IV you pair it with the Cyton board, and if you are getting the 16 Channel Mark IV you pair it with the Cyton + Daisy Boards. Nevertheless you can use all of our boards with the Mark IV.

    In addition to OpenBCI products, we also sell compatible products like the Myoware Muscle sensor and the Pulse Sensor. Both can be connected to the Cyton and Ganglion Boards to add more capabilities, they are also both compatible with the OpenBCI GUI.

    What about Software?

    You can use both the Cyton and the Ganglion with the OpenBCI GUI to get started with reading your brainwaves. Here is the tutorial on installing the OpenBCI GUI.

    Regarding third party software, the Cyton board is compatible with:

    • OpenViBE
    • neuromore studio (Bio-data acquisition, processing and visualization software)
    • BrainBay (Open-source neurofeedback application, OpenBCI tutorial here and another here)
    • BioEra (Visual designer useful for analyzing signals in real time)

    The Ganglion board is currently compatible with:

    Currently new drivers are being developed to add OpenBCI compatibility to Bioexplorer (tbd), BCI2000 (tbd), etc.

    In addition, if you are really comfortable with programming you can use MatLab or Python tools to analyze the raw data of your OpenBCI boards. For more info, head over to the For Developers Section.

    - - + + \ No newline at end of file diff --git a/FAQ/Liability/index.html b/FAQ/Liability/index.html index 88dbca09d..6c4c42a13 100644 --- a/FAQ/Liability/index.html +++ b/FAQ/Liability/index.html @@ -12,15 +12,15 @@ Liability Policy | OpenBCI Documentation - - + +
    -

    Liability Policy

    Disclaimer of medical, clinical, or diagnostic use

    OpenBCI, Inc. provides the OpenBCI-trademarked products under the following conditions: This evaluation board/kit is intended for use for ENGINEERING DEVELOPMENT, DEMONSTRATION, OR EVALUATION PURPOSES ONLY and is not considered by OpenBCI, Inc. to be a finished end-product fit for general consumer use.

    FDA approval is NOT required to use an EEG device for recording and research purposes, unless specifically required by your IRB or research +

    Liability Policy

    Disclaimer of medical, clinical, or diagnostic use

    OpenBCI, Inc. provides the OpenBCI-trademarked products under the following conditions: This evaluation board/kit is intended for use for ENGINEERING DEVELOPMENT, DEMONSTRATION, OR EVALUATION PURPOSES ONLY and is not considered by OpenBCI, Inc. to be a finished end-product fit for general consumer use.

    FDA approval is NOT required to use an EEG device for recording and research purposes, unless specifically required by your IRB or research institution.

    All official OpenBCI products are designed and assembled in the United States. OpenBCI products are not medical, clinical, or diagnostic devices nor are they intended for medical diagnosis and are provided to you "as is," and we make no express or implied warranties whatsoever with respect to its functionality, operability, or use, including, without limitation, any implied warranties, fitness for a particular purpose, or infringement.

    OpenBCI boards are designed to take power only from lowยญ-voltage DC sources, i.e. batteries. They do not take power from the โ€œgrid,โ€ from power outlets, USB ports, etc.

    Limitations of Liability.

    Persons handling the product(s) must have electronics training and observe good engineering practice standards. As such, the goods being provided are not intended to be complete in terms of required designยญ, marketingยญ, and/or manufacturing ยญrelated protective considerations, including product safety and environmental measures typically found in end products that incorporate such semiconductor components or circuit boards. This evaluation board/kit does not fall within the scope of the European Union directives regarding electromagnetic compatibility, restricted substances (RoHS), recycling (WEEE), FCC, CE or UL, and therefore may not meet the technical requirements of these directives or other related directives.

    We expressly disclaim any liability whatsoever for any direct, indirect, consequential, incidental or special damages, including, without limitation, lost revenues, lost profits, losses resulting from business interruption or loss of data, regardless of the form of action or legal theory under which the liability may be asserted, even if advised of the possibility of such damages.

    IN NO EVENT WILL OPENBCI BE LIABLE TO END USER FOR SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, PUNITIVE, OR OTHER INDIRECT DAMAGES, OR FOR LOSS OF PROFITS, LOSS OF DATA OR LOSS OF USE, ARISING OUT OF THE MANUFACTURE, SALE, SUPPLYING OR FAILURE OR DELAY IN SUPPLYING OF THE PRODUCTS OR SERVICES RELATED THERETO, WHETHER BASED UPON WARRANTY, CONTRACT, TORT, STRICT LIABILITY OR OTHERWISE, EVEN IF OPENBCI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR LOSSES. -UNDER NO CIRCUMSTANCES WILL OPENBCIโ€™S TOTAL LIABILITY TO END USER FROM ANY AND ALL CAUSES (INCLUDING NEGLIGENCE) EXCEED THE TOTAL AMOUNT PAID BY END USER FOR THE PRODUCTS.

    Governing Law/Dispute Resolution

    These terms and your use of the Products shall be governed by the law of the State of New York, U.S.A.. Any disputes arising from these terms or your use of the Products shall be heard in the state or federal courts located in New York, New York, U.S.A.

    - - +UNDER NO CIRCUMSTANCES WILL OPENBCIโ€™S TOTAL LIABILITY TO END USER FROM ANY AND ALL CAUSES (INCLUDING NEGLIGENCE) EXCEED THE TOTAL AMOUNT PAID BY END USER FOR THE PRODUCTS.

    Governing Law/Dispute Resolution

    These terms and your use of the Products shall be governed by the law of the State of New York, U.S.A.. Any disputes arising from these terms or your use of the Products shall be heard in the state or federal courts located in New York, New York, U.S.A.

    + + \ No newline at end of file diff --git a/FAQ/PaymentFAQ/index.html b/FAQ/PaymentFAQ/index.html index f0781f7a7..206317d27 100644 --- a/FAQ/PaymentFAQ/index.html +++ b/FAQ/PaymentFAQ/index.html @@ -12,14 +12,14 @@ Purchases & Payment Processing | OpenBCI Documentation - - + +
    Skip to main content

    Purchases & Payment Processing

    Please note all orders ship after full payment. Orders cannot be split between multiple shipments. To make a change to your order, please email support@openbci.com ASAP. We cannot guarantee that we can satisfy the request, but we will do our best if contacted in a timely fashion.

    How do I request a quotation or an invoice?

    There are two methods of getting a quotation. The first and faster method is to make a customer account with your email and shipping address. Then, email sales@openbci.com with a list of products wanted. We will then quickly follow up with a PDF quote.

    The second method- Please email us at contact@openbci.com, with the items you want in the quotation and the shipping address in the format below to give you an accurate shipping rate.

    First name:

    Last name:

    Email:

    Company:

    Phone number:

    Address:

    Address con't:

    City:

    Country:

    Region/State/Province:

    Postal/zip code*:

    Tax ID or VAT:

    When will my credit card be charged?

    Our store system will authorize your card the moment you place your order and a settlement (debit) will likely occur within 48 hours.

    - - + + \ No newline at end of file diff --git a/FAQ/Privacy/index.html b/FAQ/Privacy/index.html index 350c3d43b..44722658f 100644 --- a/FAQ/Privacy/index.html +++ b/FAQ/Privacy/index.html @@ -12,12 +12,12 @@ Privacy & Security | OpenBCI Documentation - - + +
    -
    Skip to main content

    Privacy & Security

    Effective June 26, 2018

    OpenBCI collects customer information in an effort to improve our customersโ€™ shopping experiences and to communicate with our customers about our products, services and promotions. OpenBCI recognizes that it must maintain and use customer information responsibly. +

    Privacy & Security

    Effective June 26, 2018

    OpenBCI collects customer information in an effort to improve our customersโ€™ shopping experiences and to communicate with our customers about our products, services and promotions. OpenBCI recognizes that it must maintain and use customer information responsibly. We value the privacy and security of our customers. We NEVER sell, rent, or disclose your information to a third-party without your express permission, and then only for the purposes of customer service related to order processing and payment, as required by law.

    1. WHO ARE WE?

    โ€œOpenBCIโ€ refers to OpenBCI, Inc a company incorporated in the USA with its registered office at 67 WEST STREET, BROOKLYN, NEW YORK, 11222. You can contact us via email at contact@openbci.com for any questions relating to our Privacy Policy.

    2. WHAT DOES THIS PRIVACY POLICY GOVERN?

    This Privacy Policy is where we explain what information is being collected when you use the OpenBCI website and products (our โ€œServicesโ€), and how that information is collected, utilized, stored and protected. This policy also explains your rights relating to the collection and use of your personal information ("Personal Information" means information which, on its own or in combination with other information, can be used to identify you). OpenBCI respects the privacy of its online visitors and customers of its products and services and complies with applicable laws for the protection of your privacy in the USA and elsewhere.

    Under European Union data protection legislation, OpenBCI is the โ€œdata controllerโ€ for personal information collected from our Services. OpenBCI works with several โ€œPartnersโ€ and Third Parties (Google, Facebook, Shopify) who are โ€œdata processorsโ€ under GDPR.

    Please read the following carefully to get a clear understanding of how we collect, use, protect or otherwise handle any Personal Information collected from the use of our Services.

    3. WHAT CONSTITUTES ACCEPTANCE OF THIS POLICY?

    By clicking โ€œI acceptโ€ on any Privacy Policy prompts, or by continuing to use the OpenBCI website and Services beyond reviewing this Privacy Policy, you are consenting to the use of your personal information as described in this Policy.

    4. WHAT PERSONAL INFORMATION DO WE COLLECT?

    The Personal Information that OpenBCI collects varies depending on your use of our Services. Not all of the below items are required for all parts of our Services; for example, payment information and shipping address are only collected when making a purchase, and are not required to access other parts of our site.

    When you use OpenBCI services we may collect the following information (how we use it is described later in this document):

    I. Contact Information: Name, Address, Phone Number, Email, Username and other basic information submitted when making a purchase, contacting us, or registering on our site. II. Linked social/external accounts: Github, personal website, or other personal social account names/URLS which you provide to us when registering for our Services, or communicating with us through social media. III. Limited financial information: information you provide to us when making purchases from OpenBCI including credit card number, expiration date, verification code, or similar information from other connected payment services (Paypal, Google Pay, Apple Pay). @@ -64,7 +64,7 @@ VI. The right to data portability; a Data Subject has the right to ask for any data supplied directly to the Data Controller by him or her, to be provided in a structured, commonly used, and machine-readable format. VII. The right to object; the Data Subject has the right to object to further processing of their data which is inconsistent with the primary purpose for which it was collected, including profiling, automation, and direct marketing. VIII. Rights in relation to automated decision making and profiling; Data Subjects have the right not to be subject to a decision based solely on automated processing.

    California residents have additional rights pursuant to Section 1798.83 of the California Civil Code. This law states that companies must inform consumers about the types of Personal Information that have been shared with third parties, who those third parties are, and examples of the types of services or products marketed by those third parties. To request a copy of the information disclosure contact@openbci.com

    15. PROTECTING CHILDREN

    We do not and will not knowingly collect personal information from any child under the age of 16. If we learn that any user of the Services is under the age of 16, we will take necessary steps to remove information about that user from all systems. If you are a parent or guardian of a child under 16 who you believe has used our Services, please contact contact@openbci.com

    16. CONTACT INFO & ENFORCEMENT

    If you have any concerns or questions about how OpenBCI handles your personal information, please contact us first. If you feel we have not dealt with your concern you have the right to lodge a complaint with the relevant national supervisory authority or EU Member State.

    17. CHANGES TO THIS POLICY

    Our Privacy Statement applies to all users worldwide. OpenBCI reserves the right to make changes to this Policy at any time. In the event we do change our Policy you will find the updated version on our website, and users will be emailed to notify them of changes. You can find the current version on our website.

    - - + + \ No newline at end of file diff --git a/FAQ/Returns/index.html b/FAQ/Returns/index.html index a28b0d038..9827aed75 100644 --- a/FAQ/Returns/index.html +++ b/FAQ/Returns/index.html @@ -12,13 +12,13 @@ RETURNS & REFUNDS | OpenBCI Documentation - - + +
    -

    RETURNS & REFUNDS

    Returns

    To initiate a return, contact us at support@openbci.com. Refunds and exchanges can be requested within 30 days of the delivery date.

    Please note, all returns are contingent on the resale-able condition of the items. The customer is responsible for the cost of return shipping.

    Order Issues

    If you received a damaged item, we will send a replacement at no additional charge, or refund the order in full, including shipping cost. OpenBCI must be notified as soon as possible after you receive your order, via support@openbci.com.

    How to Return or Exchange Items in 3 Simple Steps

    1. Contact us at support@openbci.com indicating the issue or reason for return. We will provide the return shipping address.
    2. Send us the items in the original box (or a different box, as long as it's unmarked) to the address below. We suggest you use USPS Priority Mail or a carrier that provides tracking. OpenBCI, Inc. is not responsible for lost shipments. If returning an order from outside the US, declare a low shipment value for customs, i.e. $10.
    3. Email us to let us know when to expect the package.

    If Youโ€™re Requesting a Refund

    We reserve the right to deduct up to a 10% fee based on the condition of the product(s)and the logistics cost of refurbishing and restocking. The fee is subtracted from the amount of the refund. Shipping costs are not refunded.

    When the returned item is received, your original method of payment will be credited as soon as we have completed processing your return (usually within 2 weeks).

    Policy Limitation

    The product policy outlined above is applicable only to orders from shop.openbci.com. Because OpenBCI's hardware and software files are open-source, some companies use the files to make counterfeit biosensing products. They look similar to authentic OpenBCI products but do not function or meet expectations. We are unable to offer support on counterfeit or inauthentic products.

    OpenBCI manufactures biosensing boards at a dedicated facility in the United States. We use a strict quality-control system to ensure our customers receive high-quality, research-grade products.

    - - +

    RETURNS & REFUNDS

    Returns

    To initiate a return, contact us at support@openbci.com. Refunds and exchanges can be requested within 30 days of the delivery date.

    Please note, all returns are contingent on the resale-able condition of the items. The customer is responsible for the cost of return shipping.

    Order Issues

    If you received a damaged item, we will send a replacement at no additional charge, or refund the order in full, including shipping cost. OpenBCI must be notified as soon as possible after you receive your order, via support@openbci.com.

    How to Return or Exchange Items in 3 Simple Steps

    1. Contact us at support@openbci.com indicating the issue or reason for return. We will provide the return shipping address.
    2. Send us the items in the original box (or a different box, as long as it's unmarked) to the address below. We suggest you use USPS Priority Mail or a carrier that provides tracking. OpenBCI, Inc. is not responsible for lost shipments. If returning an order from outside the US, declare a low shipment value for customs, i.e. $10.
    3. Email us to let us know when to expect the package.

    If Youโ€™re Requesting a Refund

    We reserve the right to deduct up to a 10% fee based on the condition of the product(s)and the logistics cost of refurbishing and restocking. The fee is subtracted from the amount of the refund. Shipping costs are not refunded.

    When the returned item is received, your original method of payment will be credited as soon as we have completed processing your return (usually within 2 weeks).

    Policy Limitation

    The product policy outlined above is applicable only to orders from shop.openbci.com. Because OpenBCI's hardware and software files are open-source, some companies use the files to make counterfeit biosensing products. They look similar to authentic OpenBCI products but do not function or meet expectations. We are unable to offer support on counterfeit or inauthentic products.

    OpenBCI manufactures biosensing boards at a dedicated facility in the United States. We use a strict quality-control system to ensure our customers receive high-quality, research-grade products.

    + + \ No newline at end of file diff --git a/FAQ/ShippingFAQ/index.html b/FAQ/ShippingFAQ/index.html index a97ce3856..84fb17d0e 100644 --- a/FAQ/ShippingFAQ/index.html +++ b/FAQ/ShippingFAQ/index.html @@ -12,14 +12,14 @@ Shipping & Taxes | OpenBCI Documentation - - + +

    Shipping & Taxes

    Where do you ship to?

    ALL OpenBCI orders ship from the US. We ship worldwide!

    What are the shipping rates?

    Shipping is calculated based on a number of factors including the size of the package, the postage carrier selected, and the destination. Shipping charges and delivery methods are shown at checkout. Note that shipping charges shown at checkout do not include unforeseen delivery costs such as import duty and customs taxes.

    Generally, shipping to US addresses takes less than one week. If using FedEx International Economy (the recommended courier), allow up to 1-2 weeks for your order to arrive at customs clearance. ALL orders include tracking number emailed automatically to an email you provide. This tracking number is usually made available within 2-3 business days.

    Sales Tax

    For customers in the United States, your purchase may be sales tax-free if made on behalf of a tax-exempt organization. Ask your purchasing department for the tax-exempt certificate BEFORE placing an order, and send to contact@openbci.com. We do not refund sales taxes after purchase.

    For other customers, the sales tax will be calculated automatically per the laws of the state you reside in.

    Are duties and customs included in the shipping rate?

    Countries outside the United States may be subject to import duties and customs taxes per the laws of your country of residence. As the customer, you are responsible for these charges.

    We will not intervene with customs procedures, per the import laws of your country of residence.

    Please be advised that product prices do not include customs fees, taxes, brokerage fees, or any customs clearance fees. This is the responsibility of the customer.

    If shipping to European countries, please expect the total import cost to be about 30% of the product price. For other countries, it is up to 10-20%.

    The import cost will be calculated by your customs office at the time of delivery and passed onto you. Due to the nature of international trade, OpenBCI has no control over these charges, and can give only a rough estimate from historical purchase data. Because of varied customs policies, we are unable to provide exact predictions. Please contact your local customs office if you need exact import cost information.

    For international customers, if you are purchasing on behalf of an academic or tax-exempt organization, your purchase may be exempt from some import costs. Please verify with the purchasing department of your organization before placing the order.

    - - + + \ No newline at end of file diff --git a/ForDevelopers/FirmwareDevelopment/index.html b/ForDevelopers/FirmwareDevelopment/index.html index 3b72bf74f..b09d4aa2b 100644 --- a/ForDevelopers/FirmwareDevelopment/index.html +++ b/ForDevelopers/FirmwareDevelopment/index.html @@ -12,13 +12,13 @@ Firmware Development | OpenBCI Documentation - - + +

    Overview

    Welcome all Firmware Developers! In this document, you can find a list of firmware resources for current boards. This is a great starting point if you are interested in how a board works at the firmware level or an expert user interested in modifying the firmware.

    All firmware provided here is licensed under the MIT License! Enjoy!

    CAUTION: Please be careful when uploading firmware. If not done properly, one could "brick" the hardware and it may no longer work! This is only recommended for experienced users, or at the request of OpenBCI support.

    OpenBCI Supported Firmware

    Cyton

    Cyton Dongle (RFDuino)

    Ganglion

    Third-Party Firmware

    WiFi Shield

    - - + + \ No newline at end of file diff --git a/ForDevelopers/ForDevelopersLanding/index.html b/ForDevelopers/ForDevelopersLanding/index.html index 66dcfa4ef..c064e96a7 100644 --- a/ForDevelopers/ForDevelopersLanding/index.html +++ b/ForDevelopers/ForDevelopersLanding/index.html @@ -12,13 +12,13 @@ For Developers | OpenBCI Documentation - - + +

    For Developers

    The information in this directory will help you start developing with OpenBCI technology.

    Development Options

    OpenBCI provides a range of open-source materials under the MIT license. Pages in this section include:

    Biosensing Setups

    OpenBCI allows you to customize electrode setups for various types of biosensing, as found in the Getting Started section:

    • EEG Setup โ€” Details how to wire electrodes to gather signals from the brain.
    • EMG Setup โ€” Details how to wire electrodes to gather signals from different muscle groups.
    • ECG Setup โ€” Details how to wire electrodes to gather signals from different muscle groups.

    Connect with the Community

    Looking to share what you've made? Check out the tutorial about getting started as a member of the OpenBCI Community Page:

    Need some advice from the OpenBCI Community or have an Opportunity to share? Visit the OpenBCI Forum:

    - - + + \ No newline at end of file diff --git a/ForDevelopers/HardwareDevelopment/index.html b/ForDevelopers/HardwareDevelopment/index.html index 913c49ec7..dfd65125a 100644 --- a/ForDevelopers/HardwareDevelopment/index.html +++ b/ForDevelopers/HardwareDevelopment/index.html @@ -12,13 +12,13 @@ Hardware Development | OpenBCI Documentation - - + +

    Overview

    Welcome all Hardware Developers! Are you interested in how an OpenBCI board is made? Do you want to make one yourself or incorporate one into a project? This is the place for you! Here you will find resources, including full schematics, for current and past hardware.

    All information provided here is licensed under the MIT License!


    OpenBCI Hardware

    Cyton

    Cyton Dongle (RFDuino)

    Ganglion


    OpenBCI Headwear

    Ultracortex Mark IV (June 2016 - Present)

    Ultracortex Mark III (June 2016)


    Third-Party Hardware

    WiFi Shield


    OpenBCI Forum

    - - + + \ No newline at end of file diff --git a/ForDevelopers/SoftwareDevelopment/index.html b/ForDevelopers/SoftwareDevelopment/index.html index 848fca96a..9142ce803 100644 --- a/ForDevelopers/SoftwareDevelopment/index.html +++ b/ForDevelopers/SoftwareDevelopment/index.html @@ -12,13 +12,13 @@ Software Development | OpenBCI Documentation - - + +

    Overview

    Welcome all Software Developers! In this document, we will go over the tools available to assist in integrating OpenBCI hardware with projects in multiple programming languages. Also, we will briefly look at how OpenBCI hardware is integrated into the OpenBCI GUI using Processing.

    Introducing BrainFlow

    Prior to version 5.0, the OpenBCI GUI relied on a Node.js Electron app to handle communications as middleware via TCP/IP on Mac, Linux, and Windows machines. This required users to allow a separate app to run in the background. At the same time, there are many users who just want to use OpenBCI hardware with Python, C++, or C#. The OpenBCI Community needed a solution, and we found one: BrainFlow!

    BrainFlow is written in C++ and then exported to a handful of languages. This cuts down on development time, and provides a centralized repository for OpenBCI drivers that are more accessible and accommodating.

    BrainFlow Documentation!

    Initial Setups and Testing

    GUI v5.0+ uses the BrainFlow-Java package. When starting a new project with OpenBCI hardware for the first time, it is important to check that you can connect the hardware properly, depending on your biosensing setup.

    We recommend using the GUI to start your project and check signals before moving towards full integration. Furthermore, we recommend using the GUI's Networking Widget to stream data for proof-of-concept via UDP, LSL, OSC, or Serial. This allows you to visualize real-time and playback data in the GUI while modifying your application in a separate IDE.

    Once proof-of-concept is achieved, it's appopriate to consider integrating the OpenBCI board directly into your project using one of the BrainFlow bindings, found below. The GUI can still be used at any time to check signals, make recordings, and stream live data.

    Supported Boards

    BrainFlow - C++

    BrainFlow - Python

    BrainFlow - C#

    BrainFlow - Java

    BrainFlow - R

    BrainFlow - MATLAB

    BrainFlow - Julia

    BrainFlow - Rust

    Notebooks


    OpenBCI GUI Overview

    - - + + \ No newline at end of file diff --git a/Ganglion/GanglionDataFormat/index.html b/Ganglion/GanglionDataFormat/index.html index fe8cbac01..de126d025 100644 --- a/Ganglion/GanglionDataFormat/index.html +++ b/Ganglion/GanglionDataFormat/index.html @@ -12,8 +12,8 @@ Ganglion Data Format | OpenBCI Documentation - - + +
    @@ -31,7 +31,7 @@ Channel 2 - Sample 2 - 0b1111100000000000110 - or 507910 in decimal. Note: the MSB is a 1 but this number is even because the LSB is 0

    The sample number for Sample 1 is 1 and the sample number for Sample 2 is 2. If the Byte Id was 104, Sample 1's sample number is 7 and Sample 2's sample number is 8.

    Now let's look at some negative values!


    let buffer = new Buffer(
    [
    0b01100101, // 0
    0b11111111, // 1
    0b11111111, // 2
    0b10111111, // 3
    0b11111111, // 4
    0b11101111, // 5
    0b11111111, // 6
    0b11111100, // 7
    0b11111111, // 8
    0b11111111, // 9
    0b01011000, // 10
    0b00000000, // 11
    0b00001011, // 12
    0b00111110, // 13
    0b00111000, // 14
    0b11100000, // 15
    0b00000000, // 16
    0b00111111, // 17
    0b11110000, // 18
    0b00000001 // 19
    ]);
    let expectedValue = [[-3, -5, -7, -11], [-262139, -198429, -262137, -4095]];

    Keep in mind we look to the LSB for the sign of the 19-bit number!

    The first compressed channel in sample one would be derived from the first two bytes plus the first three bits of the third byte: Channel 1 - Sample 1 - 0b1111111111111111101 - or -3 in decimal.

    The forth compressed channel in sample two would be derived from the last three bits of byte 17 and all of bytes 18 and 19: Channel 4 - Sample 2 - 0b001111100011100011 - or -198429 in decimal. The MSB is 0, yet this is a negative number because of the 1 in the LSB

    impedance

    Impedance values are sent with Byte IDs and are in ASCII format ending with a Z. Parse from byte 1 till you hit the Z.

    18-Bit Signed Data Values

    For the compressed EEG data values, you will note that we are transferring the data as a 18-bit signed integer, which is a bit unusual. We are using this number format because it is the native format used by the A/D chip that is at the core of the Ganglion board. To convert this unusual number format into a more standard 32-bit signed integer, you can steal some ideas from the example NodeJS (aka, JavaScript) code:


    /**
    * Converts a special ganglion 18 bit compressed number
    * The compressions uses the LSB, bit 1, as the signed bit, instead of using
    * the MSB. Therefore you must not look to the MSB for a sign extension, one
    * must look to the LSB, and the same rules applies, if it's a 1, then it's a
    * negative and if it's 0 then it's a positive number.
    * @param threeByteBuffer {Buffer}
    * A 3-byte buffer with only 18 bits of actual data.
    * @return {number} A signed integer.
    */
    function convert18bitAsInt32 (threeByteBuffer) {
    let prefix = 0;

    if (threeByteBuffer[2] & 0x01 > 0) {
    // console.log('\t\tNegative number')
    prefix = 0b11111111111111;
    }

    return (prefix <! 18) | (threeByteBuffer[0] <! 16) | (threeByteBuffer[1] <! 8) | threeByteBuffer[2];
    }

    19-Bit Signed Data Values

    For the compressed EEG data values, you will note that we are transferring the data as a 19-bit signed integer, which is a bit unusual. We are using this number format because it is the native format used by the A/D chip that is at the core of the Ganglion board. To convert this unusual number format into a more standard 32-bit signed integer, you can steal some ideas from the example NodeJS (aka, JavaScript) code:


    /**
    * Converts a special ganglion 19 bit compressed number
    * The compressions uses the LSB, bit 1, as the signed bit, instead of using
    * the MSB. Therefore you must not look to the MSB for a sign extension, one
    * must look to the LSB, and the same rules applies, if it's a 1, then it's a
    * negative and if it's 0 then it's a positive number.
    * @param threeByteBuffer {Buffer}
    * A 3-byte buffer with only 19 bits of actual data.
    * @return {number} A signed integer.
    */
    function convert19bitAsInt32 (threeByteBuffer) {
    let prefix = 0;

    if (threeByteBuffer[2] & 0x01 > 0) {
    // console.log('\t\tNegative number')
    prefix = 0b1111111111111;
    }

    return (prefix <! 19) | (threeByteBuffer[0] <! 16) | (threeByteBuffer[1] <! 8) | threeByteBuffer[2];
    }

    Interpreting the EEG Data

    Once you receive and parse and decompress the data packets, it is important to know how to interpret the data so that the EEG values are useful in a quantitative way. The critical piece of information is the scale factor.

    For the scale factor, this is the multiplier that you use to convert the EEG values from โ€œcountsโ€ (the int32 number that you parse from the binary stream) into scientific units like โ€œvoltsโ€. Scale factor is set and baked into the hardware, therefore use a scale factor of:


    Scale Factor (Volts/count) = 1.2 Volts * 8388607.0 * 1.5 * 51.0;

    This equation is from the MCP3912 data sheet, specifically it is from the text surrounding Table 7. This scale factor has also been confirmed experimentally using known calibration signals.

    Accelerometer data must also be scaled before it can be correctly interpreted. The equation used to scale Accelerometer data is as follows (We assume 4Gs, so 2mG per digit):


    Accelerometer Scale Factor = 0.032;

    - - + + \ No newline at end of file diff --git a/Ganglion/GanglionLanding/index.html b/Ganglion/GanglionLanding/index.html index 5aa1f946c..e6a2662bc 100644 --- a/Ganglion/GanglionLanding/index.html +++ b/Ganglion/GanglionLanding/index.html @@ -12,13 +12,13 @@ Ganglion Board | OpenBCI Documentation - - + +
    Skip to main content

    Ganglion Board

    Buy it!

    This set of tutorials will show you everything you need to know about the OpenBCI 4-channel Ganglion Biosensing Board.


    Included will be:

    • Spec Overview โ€” The specs of the board, including explanations of the components and circuit schematics.
    • Data Sheet โ€” A rundown of the defined data format for the Ganglion.
    • OpenBCI Ganglion SDK โ€” Goes over the byte string command protocol that is compatible for use with the OpenBCI Ganglion Board.
    • OpenBCI Board Programming Tutorial โ€” Tutorial explaining how to reprogram the OpenBCI Ganglion Board, allowing you to update firmware or hope to customize the board. Not needed if you wish to use the board out-of-box
    - - + + \ No newline at end of file diff --git a/Ganglion/GanglionProgram/index.html b/Ganglion/GanglionProgram/index.html index 87e607512..01bb40d91 100644 --- a/Ganglion/GanglionProgram/index.html +++ b/Ganglion/GanglionProgram/index.html @@ -12,8 +12,8 @@ Ganglion Programming Tutorial | OpenBCI Documentation - - + +
    @@ -48,7 +48,7 @@ Ganglion Pins Connection

    For this tutorial, I will use the Adafruit FTDI Friend. You can use any FTDI breakout, as long as it uses only 3V for logic levels. If you go to Adafruit to purchase one, you can also pick up some jumper wires, and 0.1uF Capacitors as well.
    IMPORTANT NOTE: THE GANGLION IS A 3V DEVICE! YOU MUST NEVER CONNECT ANY HIGHER VOLTAGE SOURCE TO ANY OF THE PINS!
    The 0.1uF capacitor needs to be in between the RESET pin of the Ganglion and the RTS pin of the FTDI breakout.

    Set Up Arduino to Program Your Ganglion

    Follow the guide at the top of this page called Build From Source all the way down till How To Create an OTA File, then come back here.

    'Simblee' selected and 'DefaultGanglion' open

    Select Simblee from menu bar Tools > Board and open the DefaultGanglion example from File > Examples > OpenBCI_Ganglion_Library > DefaultGanglion.

    Plug in Dongle or FTDI Friend and Select Serial Port

    Now is a good time to plug your Dongle in and power up the Ganglion.

    serial_port

    Verify Wire Connections and Press Upload

    With your wires all connected correctly, you should be able to click the Upload button and successfully re-program the Ganglion. Now you're ready to do OTA Programming!

    - - + + \ No newline at end of file diff --git a/Ganglion/GanglionSDK/index.html b/Ganglion/GanglionSDK/index.html index b5737a331..cb5f45bd3 100644 --- a/Ganglion/GanglionSDK/index.html +++ b/Ganglion/GanglionSDK/index.html @@ -12,8 +12,8 @@ Ganglion SDK | OpenBCI Documentation - - + +
    @@ -32,7 +32,7 @@ Read and report all register settings for the MCP and the LIS3DH. Expect to get a verbose serial output from the OpenBCI Board.

    v Soft reset for the Board peripherals.

    Firmware v2.x.x New Commands

    Supporting all v1.0.0, the v2.0.0 firmware extends the OpenBCI Ganglion system to allow for a variable sample rate.

    Sample Rate

    ~(COMMAND)
    This works similar to the Channel Settings commands, however, there is no latching character. Power cycling the OpenBCI Ganglion board will cause the sample rate to reset back to default of 200Hz.

    IMPORTANT! The Ganglion cannot and will not stream data over 200SPS. Plug in the wifi shield to get speeds over 200SPS streaming.

    COMMAND

    EXAMPLE

    First, user sends ~~

    returns Sample rate is 200Hz

    Then, user sends ~5

    returns Sample rate set to 800Hz$$$

    Wifi Shield Commands

    {"{"}

    Try to attach a Wifi Shield

    returns Success will send response Success: Wifi attached$$$ on failure response will be Failure: Wifi not attached$$$. Failure happens when the wifi shield is not powered up or the wifi shield does not power correctly. Try power cycling the system if failure continues.

    {"}"}

    Remove an attached wifi shield.

    returns Success will send response Success: Wifi removed$$$ on failure response will be Failure: Wifi not removed$$$. Failure occurs when no wifi shield is present to remove.

    :

    Get the status of the wifi shield, will either be connected or not connected.

    returns With wifi shield successfully attached will send response Wifi present$$$. If there is no OpenBCI board attached, will send Wifi not present, send { to attach the shield$$$.

    ;

    Perform a soft reset of the Wifi shield. Will do a power on reset of just the wifi shield.

    Unused ASCII Characters

    These are currently unused (and user available) characters in the OpenBCI Ganglion platform:

    a A B c C d D e E f F g G h H i I j J k K l L m M o O p P q Q r R S t T u U V w W x X y Y ` 5 6 7 8 9 0 % ^ & * ( ) - _ {"{"} {"}"} [ ] ; : ' " , . / \ | (space)

    - - + + \ No newline at end of file diff --git a/Ganglion/GanglionSpecs/index.html b/Ganglion/GanglionSpecs/index.html index ee2931688..0c0be10aa 100644 --- a/Ganglion/GanglionSpecs/index.html +++ b/Ganglion/GanglionSpecs/index.html @@ -12,8 +12,8 @@ Ganglion Specs | OpenBCI Documentation - - + +
    @@ -25,7 +25,7 @@ Ganglion Layer 2
    Bottom Layer
    Ganglion Bottom Layer

    Ganglion Board PCB Files

    OpenBCI Ganglion Board Gerber Files

    OpenBCI Ganglion Board BOM

    - - + + \ No newline at end of file diff --git a/GettingStarted/Biosensing-Setups/ECGSetup/index.html b/GettingStarted/Biosensing-Setups/ECGSetup/index.html index 558131b07..11ee6284f 100644 --- a/GettingStarted/Biosensing-Setups/ECGSetup/index.html +++ b/GettingStarted/Biosensing-Setups/ECGSetup/index.html @@ -12,15 +12,15 @@ Setting up for ECG | OpenBCI Documentation - - + +
    Skip to main content

    Setting up for ECG

    This document will show you how to read ECG data (electrical signals from the heart) using OpenBCI hardware and GUI.

    3-Lead ECG with Cyton or Ganglion Boards

    This step by step for 3-Lead ECG will show you how to get one channel of live ECG data.

    Materials Needed

    1. OpenBCI Cyton Board or Ganglion Board
    2. Skintact sticky electrodes
    3. Three EMG/ECG Snap Electrode Cables โ€” one ground and two sensors.
    4. OpenBCI GUI

    Connect Electrodes to the OpenBCI Board

    1. Connect two snap electrode cables to the top and bottom N1P pins of the Cyton.
    2. Connect a third snap electrode cable to the bottom BIAS pin of the Cyton.

    If using the Ganglion board, please refer to the following steps A to C, noting that on the Ganglion board there are up to 4 channels available, but in this 3-Lead ECG tutorial we will show you how to use one channel (to start off with!).

    A) The four switches on the Ganglion should be in the default UP position.

    B) One snap electrode cable should be connected to the bottom D_G pin (Driven Ground) of the Ganglion board. The bottom row of pins is closer to the flat surface on which your Ganglion is placed.

    C) To get one channel of data, connect one electrode cable to the top pin 1 of the Ganglion, and one electrode cable to the bottom pin 1 of the Ganglion. FYI, for future reference, you can use pins 1-4 for up to four channels of data. Nine cables, including the ground electrode in step B, are needed if you want to use all four channels of the Ganglion board.

    After making these connections, snap the Skintact sticky electrodes into the snap electrode cable. Then, remove the backing tape and apply the electrode to the skin. For safety reasons, make sure to snap the sticky electrode onto its cable before applying the sticky electrode to your skin.

    Connect the electrodes to your body

    1. Stick the ground electrode to a bony part of the chest, such as the sternum.
    2. Connect top and bottom N1P pin on the Cyton (if using Ganglion, connect +1 and -1 pins) to opposite sides of your chest.

    By doing this, we are instructing the data to measure the electric potential difference across your chest, which will in turn display your heart signals.

    Streaming ECG Data with the OpenBCI GUI

    Once you have the GUI open, turn off all channels that are not connected to electrodes by toggling the numbered data streams in the Time Series widget. If using the Cyton board, additionally go to hardware settings and turn SRB2 OFF for all of the channels that you are streaming data from.

    Note: This is because ordinarily SRB2 is the reference point from which potentials are measured, however we are now having cardiac locations reference themselves, so we do not want it to look at this pin.

    Once all of your settings have been adjusted, press 'begin data stream.'

    In the Cyton image above, note how the positive and negative terminals (yellow and green) are connected to the top and bottom N1P pins. When you are running the GUI, raw data from N1P pin will be displayed on Channel 1 within the Time Series Widget. If you are using the Ganglion, Channel 1 will show raw data from Pin 1 on the Ganglion.

    5-Lead ECG with Cyton Board

    This step by step 5-Lead ECG guide will show you how to get 4 channels of live ECG data. It builds on the above guide to 3-Lead ECG and adds only a few additional steps, so be sure to review the above sections in their entirety before getting started on the 5-Lead ECG.

    Materials Needed

    1. OpenBCI Cyton Board
    2. Skintact sticky electrodes
    3. EMG/ECG Snap Electrode Cables โ€” 4 individual cables
    4. OpenBCI GUI

    Connect the Electrodes to the OpenBCI Board and to your Body

    The standard placement of leads for a 5-lead ECG is shown below:

    5_Lead_ECG


    DiagramBody
    LALeft Arm
    RARight Arm
    LLLeft Leg
    RLRight Leg


    For a 5-Lead ECG with the Cyton board, you will need 4 Sticky Electrodes with one Snap Electrode Cable each. You'll also need to make 3 Y-cables. These cables will have 2 female header connectors spliced to 1 male header connector. The wire length can be short just a couple inches. These ribbon packages can be separated and cut, then spliced and wrapped with tape or shrink tube. An example of the jumper wires to use can be found [here](https://www.adafruit.com/product/1954).

    Follow the diagram below to connect the first 3 Sticky Electrodes. On the diagram, the โ€˜Pโ€™ means the top row of Cyton pins, and the โ€˜Nโ€™ the bottom row of pins. The lines on the diagram indicate the Y-cables that each bridge two pins. Once the Y-cables have been connected to the board, connect the electrodes to your body following the same diagram. For example, IN1P LA means you connect that Y-cable to the Left Arm location shown on chest diagram above. The V electrode is generally not used.

    5_Leads

    The last electrode cable connects the bottom BIAS pin on the Cyton to RL.



    ECG_Cyton_No_V

    Connections for 5-lead ECG, shown above

    Streaming and Visualizing ECG Data with the GUI

    Once you have the GUI open, turn off all channels that are not connected to electrodes by toggling the numbered channels in the Time Series widget. Then, go to hardware settings (located above the Time Series widget) and turn SRB2 OFF for Channels 1, 2 and 3. Turn OFF every other channel.

    Once your settings have been adjusted, press 'Start Data Stream'. You should see graphs similar to the ones below.

    ECG_GUI_No_V

    Data streaming, shown above

    Improving Signal Quality

    For help minimizing noise and improving ECG signal quality, check out this document and head to the OpenBCI Technical Forum if you have questions.

    Concerned about the signal quality? Read this paper to learn more about the reliability of OpenBCI ECG quality.

    - - + + \ No newline at end of file diff --git a/GettingStarted/Biosensing-Setups/EEGSetup/index.html b/GettingStarted/Biosensing-Setups/EEGSetup/index.html index 9f32a0896..5ccba4935 100644 --- a/GettingStarted/Biosensing-Setups/EEGSetup/index.html +++ b/GettingStarted/Biosensing-Setups/EEGSetup/index.html @@ -12,14 +12,14 @@ Setting up for EEG | OpenBCI Documentation - - + +
    Skip to main content

    Setting up for EEG

    This page will explain the most basic setup to process EEG Data using your OpenBCI board, using our gold cup electrodes.

    To learn more about specific OpenBCI Headware and how to set them up for EEG, follow the links below.

    What you will need

    What You Need

    Necessary:

    Before applying ten20 paste on subjects with long hair, refer to this guide on parting the hair for 10-20 international standard electrode positions.

    If you are using an OpenBCI electrode starter kit, use the following electrodes so as to be consistent with the GUI's color-coding protocol:

    1. Black
    2. White
    3. Purple
    4. Green
    5. Blue
    6. Red

    Optional:

    • Paper towels for cleaning excess Ten20 paste
    • Medical tape (or other tape) for adding extra stability to electrodes
    • Ear swabs for cleaning paste from electrodes, once you're finished

    1. Connect your electrodes to OpenBCI

    Connect the electrode wires to your Cyton board as shown below. The proper wire connections are shown in table form as well. You can see in the image below pins N1P through N8P on the Cyton. These correspond to the 8 channels available for data.

    On the Ganglion you have pins 1 through 4, corresponding to Ganglion's 4 channels available for data. Please note, the four switches on the Ganglion should be set to 'DOWN' for EEG. Explanation in detail here.

    eegGoldCupSetup

    Electrode Wire ColorCyton Board PinGanglion Board PinFunction
    whiteSRB2 (bottom SRB pin)REF (top pin)Reference Pin
    blackbottom BIAS pinD_G (top pin)Noise-cancelling Pin
    purple2N (bottom N2P pin)+2 (on top row)Analog input
    red7N (bottom N7P pin)+4 (on top row)Analog input

    The white and black electrodes must always connect to the SRB2 pin and the bottom BIAS pin, but the purple, and red electrodes can be connected to any of N1P through N8P channels (or pins 1 through 4 in the case of the Ganglion). We decided to use channels 2 and 7 for this tutorial. The results with Ganglion should be the same, but signals will show up on channels 2 and 4.

    2. Connect your electrodes to your head and body

    Electrode Paste

    a) We're going to start with the electrodes on your head. Begin by scooping Ten20 electrode paste into your white gold cup electrode. This is going to be your reference (or SRB2) electrode for the other electrodes on your head. Fill the electrode so there is a little extra electrode paste spilling over the top of the gold cup, as seen in the picture to the right.

    Note: Use a paper towel or napkin to remove excess electrode paste as you are applying your electrodes.

    SRB2

    b) Now apply this electrode to either one of your earlobes (either A1 or A2 as seen on the 10-20 system image below). You can use some medical tape (or electric tape!) to give this electrode some extra stability, ensuring that it does not fall off. This electrode is the reference that all of the EEG electrodes on your head will be measured in comparison to. The uV reading that will appear in the GUI's EEG DATA montage is a measure of the potential difference between each electrode and this reference electrode (SRB2). SRB1 (the top SRB pin) can also be used as a reference pin, but we won't discuss that here. Check out the other docs on how to maximize the usage of the other pins!

    Fp2

    c) Follow the same procedure for the purple electrode and apply it to your forehead 1 inch above your left eyebrow (as if you were looking at yourself) and an inch to the left of your forehead's centerline.

    1020

    This electrode location is Fp2 on the 10-20 System. The 10-20 System international standard for electrode placement in the context of EEG. Fp indicates the a "frontal polar" site.

    O1

    d) Now follow the same procedure for the red electrode and place it on the back of your head, 1 inch above the inion (as seen on the 10-20 system), and 1 inch to the left. This electrode location is O1 on the 10-20 system. The 'O' stands for occiptal, meaning above your occipital lobe (or visual cortex).

    Note: to do this, pull your hair aside and make sure the electrode is nested as deeply as possible, with the electrode paste making a definitive conductive connection between your scalp and the gold cup.

    headband

    e) Now follow the same procedure as step 2 above to apply the black electrode to your other earlobe (either A1 or A2 from the 10-20 system). The black electrode is connected to the BIAS pin, which is used for noise cancelling. It is similar to a GROUND pin, which establishes a common ground between the Cyton board and your body, but it has some extra destructive interference noise cancelling techniques built in!

    You're now done connecting electrodes to your noggin! I like to use a cheap cotton hairband to add extra stability to all of the electrodes connected to my head, by placing it gently on top of all of the electrodes.

    3. Launch the GUI and adjust your channel settings

    a) If your OpenBCI GUI is not already running, relaunch it and configure the DATA SOURCE mode to LIVE (from Cyton) and Serial (from Dongle). Select your Cyton board from the list of devices, set the Channel Count to 8, and click START SYSTEM. Refer to section IV of this guide for more information on this process.

    If you're using the Daisy Cyton board, still set the Channel Count to 8, even though the Daisy has 16 channels. Nothing will go wrong if you start the system with 16 channels, except the Time Series display will be unnecessarily cluttered.

    b) Click START DATA STREAM to begin streaming data from your board. You should see live data from your body (and the unattached channels) streaming into the Time Series montage on the left side of the GUI.

    Power Down

    c) Now we are going to power down the channels we aren't using. Do this by clicking the circular channel number buttons outside of the left side of the Time Series montage. Each time you power down a channel, the channel will show a burst of signal and then settle at 0 mV.

    Signals At Start

    We are only using channels 2 and 7, so power down every other channel. You can also power down the channels with keyboard shortcuts (1-8). Power them back up with [SHIFT] + 1-8. If you are working with a daisy module, channels 9-16 can be powered down with q, w, e, r, t, y, u, i, respectively. You can power those channels back up with [SHIFT] + the same key.

    Don't bother with the ohm symbols to the right of the buttons with numbers; they are used for impedance measuring, but we won't go into that now.

    d) Now it's time to optimize your Cyton board's channel settings for this setup. Click the Hardware Settings button above the data oscilloscope display and an array of buttons should appear in place of the Time Series montage. The Hardware Settings that are configured when you first open the GUI set every channel to EEG mode (Included in BIAS with SRB2 On) with a Gain of 24.

    Hardware Settings

    The dropdowns inside the Hardware Settings controller indicate the current settings of the ADS1299 registers on your Cyton board. For more information on these settings, refer to pages 39-47 of the ADS1299 datasheet.

    We have simplified the interface through the OpenBCI firmware and OpenBCI GUI to allow easy, real-time interaction with these registers. For more information on this, please refer to our doc page regarding the ADS1299 interface.

    By deactivating channels 1, 3, 4, 5, 6, and 8, those channels were automatically removed from the BIAS and SRB2, so as not to interfere with the signal.

    e) After updating these settings, click Send to send the updated settings to the board. Then click the Time Series button again to view the data.

    4. Alpha brain waves (EEG)

    Alpha Brain Waves!

    Now, for what we've all been waiting for... let's check out some brain waves!

    It's best to do this portion of the tutorial with a friend. You'll understand why in a second. It just so happens that the easiest way to consciously produce brain waves is by closing your eyes. When you do this, your occipital lobe (the part of your brain responsible for processing visual information) enters into an alpha wave state at a frequency between 7.5-12.5 Hz. Alpha brain waves are the strongest EEG brain signal! Historically, they are thought to represent the activity of the visual cortex in an idle state. An alpha-like variant called mu (ฮผ) can be found over the motor cortex (central scalp) that is reduced with movement, or the intention to move [Wikipedia].

    For more information on Alpha waves check out Wikipedia and Chip's EEG Hacker blog post about detecting alpha waves with OpenBCI V3.

    Once you've closed your eyes, have your friend press the 'm' key on your keyboard to take screenshots. Tell him or her to wait until a strong alpha spike emerges on the Fast Fourier Transform (FFT) Graph, the graph in the lower-right of the GUI. The spike should be somewhere between 7.5-12.5 on the the x-asix of the FFT graph, indicating that there is a strong presence of waves in that frequency range.

    After you've taken a few good screenshots, open up the .JPGs and take a look. Note: the screenshots are located in the root directory of your application, or in the OpenBCI_GUI directory if you are working from Processing.

    You'll notice that the strongest alpha wave signals should be appearing in channel 7, the O2 (O standing for occipital) electrode on the back of your head. Count the number of waves in a single 1-second time period on channel 7 of the EEG DATA montage. The number of waves should correspond x-axis position of the spike on the FFT graph. If you've identified your alpha waves, congratulations! You've now seen your first brain waves with OpenBCI!

    Improving Signal Quality

    For help minimizing noise and improving the quality of your EEG signals, check out this document

    - - + + \ No newline at end of file diff --git a/GettingStarted/Biosensing-Setups/EMGSetup/index.html b/GettingStarted/Biosensing-Setups/EMGSetup/index.html index dc64213d2..d3c6d0906 100644 --- a/GettingStarted/Biosensing-Setups/EMGSetup/index.html +++ b/GettingStarted/Biosensing-Setups/EMGSetup/index.html @@ -12,8 +12,8 @@ Setting up for EMG | OpenBCI Documentation - - + +
    @@ -22,7 +22,7 @@ Each circle and box represents a channel. The circle and box fill up as the amplitude of the signal on that channel increases (unit in voltage).

    Check out the gif above to see how this widget behaves when flexing and relaxing your muscle. Refer to the GUI Widget Guide for more information on this and all other GUI widgets.

    Obtain EMG Data with OpenBCI Ganglion Board

    1. Hardware Connections

    If using the Ganglion, please check your set-up with these following steps, noting that on the Ganglion board there are 4 channels available.

    Before starting, check that the four switches on the Ganglion are in the default UP position.

    Connect one snap electrode cable to the +1 pin and one snap electrode cable to the -1 pin.

    To obtain multiple EMG channels, connect snap electrode cables to pins 2 through 4 in the same way as you did for pin 1, until you have the desired number of channels. Remember, one channel per muscle, up to four channels.

    After you have done this, connect one snap electrode cable to the bottom D_G pin (Driven Ground). This will be the universal reference point.

    for reference, "bottom" pins means the row of pins closer to the table when the board is laid flat.

    After making these pin connections, connect one sticky electrode (or the IDUN Dryode if you are using that) to each snap electrode cable prior to applying the electrodes to the skin.

    2. Electrode-Muscle Connection

    Choose muscle groups that can be flexed and relaxed easily. Place one sticky electrode or (IDUN Dryode) at the base of the muscle, and the other electrode at the opposite end of the muscle. The order of these doesnโ€™t matter, as long as they are both linked to the same channel number. Place the reference electrode on a bony part of the body with as few muscles as possible (e.g. elbow, kneecap).

    Each muscle should have two electrodes - one electrode connected to the Ganglion top pin, one electrode to the Ganglion bottom pin. You can connect up to four muscles to the analog input channels 1 through 4. Thus, nine cables, including the reference electrode, are needed to get 4 channels of EMG data with the Ganglion Board.

    Electrode Wire ColorGanglion Board PinBody LocationPurpose
    blackbottom D_G pinelbowreference
    yellowtop pin 1musclemeasuring potential difference for channel 1
    greenbottom pin 1musclemeasuring potential difference for channel 1

    if you are sampling EMG from a leg muscle, use the kneecap as a reference instead.

    3. Streaming EMG Data with the OpenBCI GUI

    Once you have the GUI open, turn off any channels that you have not connected to muscle sensors, toggling the number next to the channel, in the Time Series widget.

    When you are running the GUI, data from top/bottom pin 1 will be displayed on Channel 1 within the Time Series Widget. Data from top/bottom pin 2 will be displayed on Channel 2, and so on and so forth.

    Once you are happy with your software and hardware settings, press "BEGIN DATA STREAM." Here is an example of what your data stream should look like as you flex and relax your muscle:

    EMGGIF

    4. Using the OpenBCI GUI EMG Widget

    The OpenBCI GUI also has a widget for visualizing EMG data. To view it, click on the drop down menu in the top left of any widget and select "EMG". Each circle and box represents a channel. The circle and box fill up as the amplitude of the signal on that channel increases (unit in voltage).

    Check out the gif above to see how this widget behaves when flexing and relaxing your muscle. Refer to the GUI Widget Guide for more information on this and all other GUI widgets.

    Improving Signal Quality

    For help minimizing noise and improving the quality of your EMG signals, check out this document.

    For troubleshooting or technical support, please visit the OpenBCI Technical Forum.

    Additional Tutorials

    Ready for more advanced eye, facial, and body EMG set-ups that will allow you to scroll, control music and lights, and much more? Head to Example Projects!

    - - + + \ No newline at end of file diff --git a/GettingStarted/Biosensing-Setups/ExGSetup/index.html b/GettingStarted/Biosensing-Setups/ExGSetup/index.html index 28915fcbb..8a5f7435b 100644 --- a/GettingStarted/Biosensing-Setups/ExGSetup/index.html +++ b/GettingStarted/Biosensing-Setups/ExGSetup/index.html @@ -12,8 +12,8 @@ Setting up for EEG, EMG, and ECG at the same time | OpenBCI Documentation - - + +
    @@ -58,7 +58,7 @@ EEG on Cyton

    If everything connects correctly, you should see the 3-channel EEG, ECG, and EMG in the GUI. Check the following GIF for some signature signal in these physiological data streams. ExG Demo Video

    - - + + \ No newline at end of file diff --git a/GettingStarted/Boards/CytonGS/index.html b/GettingStarted/Boards/CytonGS/index.html index 3c3afbded..7bc15f714 100644 --- a/GettingStarted/Boards/CytonGS/index.html +++ b/GettingStarted/Boards/CytonGS/index.html @@ -12,8 +12,8 @@ Cyton Getting Started Guide | OpenBCI Documentation - - + +
    @@ -23,7 +23,7 @@ IMPORTANT Make sure that there are not other Cytons active in the neighborhood when you change the channel!

    Click on the OVERRIDE DONGLE button to change the channel of the OpenBCI Dongle only. When you click the button, a menu will open up with the channels. For the purpose of this Tutorial, go ahead and change the Dongle channel to Channel 15. When you click on the channel number, it will take just a second, and you should get the message Success: Host override - Channel number: 15

    Since you have just changed the channel of the Dongle only, When you click on the STATUS button, you will get a failure message. Similarly, when you press the GET CHANNEL button you will also get a failure message. But don't worry! We can use the Autoscan function to get your Cyton Board and Dongle back on the same track!

    Now, click the AUTOSCAN button. It may take a few seconds for the Dongle to scan through every channel until it connects to your Cyton, but it will, and you will get the message Success: System is Up Autoscan!

    Edit the Playback file name

    File Name

    In the DATA LOG FIlE section of the LIVE (from Cyton) sub-panel you can specify the name of your playback file. This file name is automatically defaulted to:

    \Documents\OpenBCI_GUI\OpenBCI-RAW- + date/time

    You can edit the the name of this file by clicking in the "File Name" text field.

    Playback files and user data are stored in /Documents/OpenBCI_GUI/ on all OS. OpenBCI Playback Files use CSV formatting and plain text.

    After creating a Playback file, it can be replayed by running Playback File data source mode. As a result, you can easily share recorded OpenBCI Playback files with your friends and colleagues.

    Select your SD setting

    WRITE TO SD

    If you want to log data to a MicroSD inserted into the Cyton Board, in the WRITE TO SD (Y/N)? sub-panel section you can select the maximum recording time of the file. This setting is defaulted to "Do not write to SDโ€ฆ" and will automatically switch to this if you do not have a MicroSD card properly inserted into your Cyton board.

    Note: be sure to select a file size that is larger than your planned recording time. The Cyton writes to the local SD in a way that enables us to write lots of data very quickly. As a result, however, we must specify how large the file will be before we begin. The technique is known as block writing.

    7. Press "START SYSTEM"

    START SYSTEM

    Now you're ready to start the system! Press the START SYSTEM button and wait for the OpenBCI GUI to establish a connection with your Cyton board. This usually takes ~5 seconds.

    Initializing

    During this time, the help line at the bottom of the OpenBCI GUI should be blinking the words: "Attempting to establish a connection with your OpenBCI Board..."

    TROUBLESHOOTING

    If the initialization fails, try the following steps in order:

    1. Making sure you've selected the correct serial/COM port
    2. Power down your Cyton board and unplug your USB Dongle. Then, plug back in your USB Dongle and power up your Cyton board in that order. Then try restarting the system, but pressing the START SYSTEM button again.
    3. If this does not work, try relaunching the OpenBCI GUI application and redo step 2 above. Then reconfigure the SYSTEM CONTROL PANEL settings, and retry START SYSTEM.
    4. Make sure that your batteries are fully charged and then retry the steps above.
    5. If the channel number is not being displayed, select "AUTOSCAN" from the RADIO CONFIGURATION settings.
    6. If you are still having troubles connecting to your Cyton board, refer to the Forum for extra troubleshooting advice.

    8. Your Cyton is now live!

    Now that the OpenBCI_GUI is connected to your Cyton you may press Start Data Stream in the upper left hand corner.

    cyton serial data stream start

    You should see data streaming into the GUI, try running your fingers along the electrode pins at the top of your board.

    Touch

    You should see the 8 (or 16 if you're using a Daisy module) channels on the Time Series widget behave chaotically in response to you touching the pins and all the traces of the FFT graph on the upper right should instantly shift upwards.

    cyton serial chaos

    If this is the case, congratulations! You are now connected to your Cyton board. It's time to see some brain waves! Learn about the Time Series and other built-in widgets in the GUI Widget Guide.

    info

    By default, the GUI stores all user data and raw EEG recordings in [USER]/Documents/OpenBCI_GUI and names each session with an autogenerated timestamp by default.

    Experts and those interested in communicating directly with the board can refer to the Cyton Data Format Guide to learn how to interpret the raw data coming straight from the device. However this is already handled gracefully by BrainFlow for a number of programming languages and use cases.

    V. Connect yourself to OpenBCI

    To learn how to connect yourself to OpenBCI using your newly set up board, see the following tutorials:

    In the above setups, you may need to adjust the Hardware Settings of the ADS1299 chip, the core piece of technology in the Cyton. Click here for more info on Cyton Hardware Settings UI in the Time Series Widget. If you are an advanced user, you can look at the GUI console log after changing hardware settings and the Cyton SDK Guide to learn how to send custom commands to the Cyton using any BrainFlow binding.

    VI. Fixing FTDI Buffering on Mac OS

    On some Macs, you may have noticed that the data coming from your Cyton board is very choppy. Newer Macs (mid 2015 - present) may not have this issue and can connect flawlessly to the Cyton using the Dongle sold with each Cyton.

    This is a result of the FTDI virtual com port (VCP) driver's default settings for macOS. Head over to the FTDI Driver Fix Guide to see how to adjust the settings.

    VII. Fixing FTDI Buffering on Windows

    The default FTDI latency is too large for EEG applications, making the incoming signal "choppy" and seem as if its accumulating packets for about a full second before releasing them all at the same time into the serial stream. Head over to the FTDI Driver Fix Guide for Windows to see how to adjust the settings.

    VIII. Fixing FTDI Latency on Linux

    - - + + \ No newline at end of file diff --git a/GettingStarted/Boards/DaisyGS/index.html b/GettingStarted/Boards/DaisyGS/index.html index f95d09dc2..d116c8d76 100644 --- a/GettingStarted/Boards/DaisyGS/index.html +++ b/GettingStarted/Boards/DaisyGS/index.html @@ -12,14 +12,14 @@ Daisy Getting Started Guide | OpenBCI Documentation - - + +
    Skip to main content

    Daisy Getting Started Guide

    This guide will walk you through getting 16-channel input on your Cyton+Daisy Module

    I. SET UP YOUR CYTON BOARD

    Refer to the Cyton Tutorial page: Cyton Getting Started Guide.

    Follow the guide through the end of Step V. CONNECT YOURSELF TO OPENBCI

    II. WHAT YOU NEED

    1. OpenBCI Daisy Module
    2. Y-Splitter Cable
    3. Electrode cables with female header termination on one end

    1. OpenBCI Daisy Module

    2. Y-Splitter Cable

    3. Electrode Cables with female header termination on one end

    III. ASSEMBLY

    1) Attaching the Daisy

    OPTION A) Attach Wifi Shield before attaching Daisy

    If you purchased a Wifi Shield, attach it to the Cyton board, then attach the Daisy module on top of the Wifi Shield, shown below.

    The leads are connected to the pins in the same way as if you did not have the Wifi Shield. Skip to step 3 to connect Y-splitter cable.

    For more information on powering the Wifi shield, check out the Wifi Getting Started Guide.

    OPTION B) Add the Daisy extension directly onto the Cyton Board

    If you are using the OpenBCI USB Dongle, attach the Daisy module on top of the Cyton Board, shown below.

    2) Connect Y-Splitter Cable

    The Y-Splitter connects the bottom SRB pin of the Daisy Board to the bottom SRB pin of the Cyton Board. The single end of the Y-Splitter connects to a reference point i.e. the earlobe or mastoid.

    3) Connect the bottom BIAS pin of the Cyton to a second reference point

    Usually, the earlobe is used as the reference point, because it has no muscle or neurons and therefore very low electrical signals.

    4) Connect Cyton bottom pins N1P-N8P and Daisy bottom pins N1P-N8P to leads

    Use the 16 of the color coded cables that came with your Ultracortex MarkIV headset.

    Connect Cyton bottom pins N1P through N8P to the cables, shown above. Then, connect the remaining 8 cables to Daisy bottom pins N1P through N8P. Color order does not matter.

    Refer to the Ultracortex Mark IV tutorial to learn how to connect the male terminations of the color coded cables to the electrodes on the headset.

    If you did not purchase a headset, you can use 16 of our Gold Cup Electrodes, Snap Electrode Cables, or Header Pin to Touch Proof Electrode Adapter.

    - - + + \ No newline at end of file diff --git a/GettingStarted/Boards/GanglionGS/index.html b/GettingStarted/Boards/GanglionGS/index.html index 6a10dbc3a..0dafec740 100644 --- a/GettingStarted/Boards/GanglionGS/index.html +++ b/GettingStarted/Boards/GanglionGS/index.html @@ -12,8 +12,8 @@ Ganglion Getting Started Guide | OpenBCI Documentation - - + +
    @@ -21,7 +21,7 @@ If you are using a non-OpenBCI battery holder, please check the polarity (red +/black -) BEFORE powering up your OpenBCI board. A reversed polarity will burn out your board.

    4. (x4) Plastic Feet

    Plastic Feet

    Your OpenBCI kit comes with 4 plastic feet that can be snapped into the holes of your board to provide extra stability while working.

    5. Gold Cup Electrodes and Paste

    Electrode Starter Kit

    If you ordered OpenBCI Gold Cup Electrodes and Electrode Paste, it should come with:

    TouchProof Adapter

    If you plan to work with your own electrodes, the Touch-Proof Adapter will come in handy. It will convert any electrode that terminates in the industry-standard touch-proof design to an electrode that can be plugged into any OpenBCI Board!

    Download/Install/Run the OpenBCI GUI

    Please follow the step by step guide to install the OpenBCI_GUI as a standalone application.

    Come back to this guide when your GUI is running!

    Start Using The OpenBCI GUI

    Connect the GUI to your Ganglion board

    Make sure your computer's Bluetooth feature is turned on. Select LIVE (from Ganglion) from the first drop down.

    selecting ganglion from drop down

    Select Bluetooth (BLED112 Dongle) as the transfer protocol.

    selecting ganglion ble from the transfer protocol

    The GUI will automatically start searching for Ganglion devices.

    Each Ganglion has its own unique 4 character ID (in HEX), and you will see it listed in the BLE DEVICES window. If you don't see any Ganglions, check to make sure your Ganglion has a battery connected, is switched on, and the blue LED is blinking. If there are multiple Ganglions in the room, you can find yours by turning it off, clicking the REFRESH LIST button, then turn on your Ganglion again. Make a note of your Ganglion's 4 character ID.

    Select the desired Ganglion device from the dropdown list.

    selecting your ganglion ble shield

    The GUI will automatically generate a recording to a file. You have an option at this point to create your own file name, in the DATA LOG FILE window, should you choose to.

    File Name

    Press START SYSTEM when you're ready to begin streaming.

    ble ganglion start system

    When the GUI connects, it opens up to the default window layout. For a more in-depth guide to the GUI interface and functionality, check out the OpenBCI GUI doc. For the purposes of this introductory tutorial, You should follow the following steps to setup the GUI.

    Start Data Stream

    Click on the Layout dropdown menu, and select the one outlined in red.

    select layout

    If the Accelerometer is off, turn on the Accelerometer by clicking the Turn Accel. On button.

    Accel ON! Accel ON!

    Then, click Start Data Stream to stream data from your Ganglion board.

    Start Data Stream First Live Ganglion Data

    You should see the Time Series window scrolling some data to the left, the FFT Plot container will show you the power level of the signals at different frequencies. The Accelerometer window will also scroll data.

    info

    By default, the GUI stores all user data and raw EEG recordings in [USER]/Documents/OpenBCI_GUI and names each session with an autogenerated timestamp by default.

    Learn about the Time Series and other built-in widgets in the GUI Widget Guide. Refer to the Ganglion Data Format guide to learn how to interpret the raw data directly from the device. However this is already handled gracefully by BrainFlow for a number of programming languages and use cases.

    Accel Moving

    Pick up your board, and move it around. You should see the data in the Accelerometer window also move around, and if you're touching the input pin header, you will see some noise in the other windows. Nice!

    NOTE: If you're having connection issues, refer to the troubleshooting tips below.

    Now that you've got your computer connected to the Ganglion, it's time to connect your self!

    Connect yourself to OpenBCI

    To learn how to connect yourself to OpenBCI using your newly set up board, see the following tutorials:

    - - + + \ No newline at end of file diff --git a/GettingStarted/Boards/WiFiGS/index.html b/GettingStarted/Boards/WiFiGS/index.html index 1249d7762..f37c9a625 100644 --- a/GettingStarted/Boards/WiFiGS/index.html +++ b/GettingStarted/Boards/WiFiGS/index.html @@ -12,15 +12,15 @@ WiFi Shield Getting Started Guide | OpenBCI Documentation - - + +
    Skip to main content

    WiFi Shield Getting Started Guide

    Overview

    The OpenBCI WiFi Shield is a hardware product, intended to work with the OpenBCI GUI software and be paired with any OpenBCI board, that enables biodata streaming over wifi. The advantage of wifi over bluetooth is increased sampling rate. The WiFi Shield increases the sample rate by transmitting the data via WiFi as opposed to Bluetooth. The WiFi Shield can be controlled through HTTP requests and can send JSON objects with data in nano volts. With the WiFi Shield connected:

    • The Cyton can stream data at 50Hz, 500Hz, 1000Hz, 2000Hz, 4000Hz, 8000Hz and 16000Hz.

    • The Cyton + Daisy can stream data at 250Hz, 500Hz, 1000Hz, 2000Hz, 4000Hz, and 8000Hz.

    • The Ganglion can stream data at 200Hz, 400Hz, 800Hz, 1600Hz, 3200Hz, 6400Hz, and 12800Hz

    IMPORTANT NOTE: This product is in beta mode. The WiFi shield is known to have reliability issues (packet loss and cyclical noise spikes) when used with Cyton and CytonDaisy boards. Using it effectively requires advanced technical skills and programming knowledge. Please proceed at your own risk. OpenBCI cannot guarantee that the device will work with your configuration.

    When connecting to Cyton+WiFi or Cyton+Daisy+WiFi using the OpenBCI GUI, you have the option of using TCP, UDP, or UDPx3. We recommend trying to connect using UDPx3 protocol.

    Prerequisites

    The WiFi Shield requires your Cyton to run the latest Cyton firmware and your Ganglion to the latest Ganglion firmware firmware. PLEASE NOTE IF YOU PURCHASED YOUR OPENBCI BOARD MID-2018 OR LATER, YOU DO NOT NEED TO UPDATE ITS FIRMWARE.

    This guide will walk you through setting up your WiFi Shield, connecting it to your computer, and then connecting it to yourself. The first tutorial is for the Cyton and the second is for the Ganglion.

    When setting up the WiFi Shield to connect to a local network or hotspot, the WiFi needs to be powered independently. Please make sure the WiFi shield is unplugged from a Ganglion or Cyton during setup, otherwise it may not work.

    Cyton with WiFi Shield

    OpenBCI Cyton Wifi Contents

    Expand this section for Cyton + WiFi Shield instructions

    What you need

    1. OpenBCI WiFi Shield
    2. OpenBCI Cyton Board
    3. One LiPo battery or 6V AA battery pack & (x4) AA batteries (batteries not included)
      • You only need one battery when using the Cyton with the WiFi Shield. The Cyton takes power from the WiFi Shield. When the Cyton is powered by the WiFi Shield, you'll find the power switch on the Cyton becomes useless.

    General Overview

    In general the steps are:

    1. Power off WiFi Shield and Cyton
    2. Seat WiFi Shield on Cyton
    3. Put EXT PWR switch on the WiFi Shield to ON
    4. Plug battery into WiFi Shield only (do not plug a battery into the Cyton)
    5. Main power switch on WiFi Shield to ON

    Powering the Shield

    Install 4 AA batteries in your battery pack or charge up your LiPo battery. The Wifi shield has a larger power draw than the Bluetooth communication system so we recommend using LiPo battery packs. The Cyton is not able to supply enough current to power the power-hungry wifi shield, so we put a bigger voltage regulator on the shield to power both the Wifi chip and pass the Cyton components.

    IMPORTANT! Keep the dip switch labeled EXT PWR to ON when using Cyton.

    Wifi External Power

    The Wifi Shield and the Cyton board use only one battery by means of the JST connector on the Wifi shield. The pass through LED (the right most LED) on the wifi shield will show the solid blue LED from the Cyton below.

    Wifi Pass Through Power

    NOTE ABOUT ANALOG/AUX MODE

    When switching the board mode to analog/aux, the D4 light turns off. This can be done in the OpenBCI GUI, or running this in python:


    from openbci import wifi as bci
    shield = bci.OpenBCIWiFi(ip_address = '192.168.1.141', log=True, high_speed=True)
    shield.wifi_write('/2') #analog mode

    Observe that light D4 turns off. This is normal. In order for the LED to turn on the Cyton has to set that pin as an output HIGH. When the Cyton switches into digital/analog inputs it changes the pin driving the D4 LED to INPUT, so the is no longer receiving any current to turn on.

    Ganglion with WiFi Shield

    Expand this section for Ganglion + WiFi Shield instructions

    What you need

    1. OpenBCI WiFi Shield
    2. OpenBCI Ganglion Board
    3. Two batteries, 3.7V or 4.2V LiPo or 6V AA battery will work (batteries not included)

    General Overview

    In general the steps are:

    1. Power off WiFi Shield and Ganglion
    2. Seat WiFi Shield on Ganglion
    3. Put EXT PWR switch on Shield to OFF
    4. Plug battery into Ganglion
    5. Plug battery into WiFi Shield
    6. Main power switch on WiFi Shield to ON
    7. Main power switch on Ganglion to ON

    Powering the Shield

    The Ganglion runs at 3.0 Volts while the WiFi Shield runs at 3.3 Volts. You can use the WiFi shield to power the Ganglion; using the Ganglion to power the WiFi Shield is not recommended. Install 4 AA batteries into your battery packs or charge up your LiPo batteries. The Wifi shield draws more current than the Ganglion so we recommend using LiPo rechargeable batteries to power the Wifi Shield.

    To use one battery, flip EXT PWR in the ON position. You can use the black spudger tool that came with your WiFi Shield.

    To use two batteries, keep EXT PWR in the OFF position, or flip it to OFF in case it is ON.

    EXT PWR ON/OFFEXT PWR is ON in top photo, OFF in bottom photo.

    With two batteries, always power the WiFi Shield before the Ganglion.

    Two batteries for ganglion with wifi shield

    Battery Connection

    WiFi Configuration for Firmware 2.0 and later

    WiFi Shields got powerful in firmware 2.0.0, we learned a lot and iterated continuously, we love the new features on the WiFi Shield, by "we" meaning a worldwide community of empowered hackers and researchers alike.

    WiFi Shield Mode of Operations

    There are two modes primary modes of operation for the WiFi Shield, WiFi Station and WiFi Direct. The D2 LED status light is used to indicate what mode of operation the WiFi Shield is in at start up.

    WiFi Station

    WiFi Station shipped as the only option with v1.3.0 firmware. WiFi Station mode connects your WiFi Shield to a WiFi Router, such as your home wireless network that you watch Netflix on... The WiFi Shield uses 802.1 b/g/n and sends a lot of data, especially as we increase data rates and number of channels, slow or far routers can result in data loss. We introduced UDP and UDP burst mode in firmware 2.0.0 that we hear runs great.

    WiFi Station is not a realistic mode of operation when you are at a conference, hack-a-thon, universities with enterprise level security, doing a live demo, etc... The community pushed hard and introduced WiFi Direct mode of operation.

    WiFi Direct

    WiFi Direct bypasses a WiFi router by having your computer or phone connect directly to a wireless network broadcasted by the WiFi Shield. The WiFi Direct mode allows for high speed data streaming, such as 1000Hz with 16 channels with zero compression, these speeds and data throughputs are digested easily in this peer to peer WiFi data transfer mode.

    Status D2 LED Indicator

    If your D2 LED Indicator light stays solid on at start-up, it's highly recommended you follow the tutorial for , you must update your firmware with an over the air update to 2.0.0 or later.

    If the WiFI Shield is not able to join a wireless network, such as when the saved wireless network is not in range or the WiFi shield has no credentials saved in memory, the WiFi will be in WiFi Direct mode. The D2 LED indicator will blink 10 times in 2 seconds to indicate the WiFi Shield is in WiFi Direct mode.

    If there are saved wireless network credentials on the WiFi Shield, the WiFi Shield will blink 4 times in 2 seconds to indicate the WiFi Shield is searching for the stored wireless network. If the stored network is found, the WiFi Shield will join the wireless network and blink 2 times in 2 seconds; the WiFi Shield is now in WiFi Station mode. If the stored network is not found within 10 seconds, the WiFi Shield will switch into WiFi Direct mode.

    The WiFi Manager, the tool used to store wireless network credentials onto the WiFi shield, may be launched in either WiFi Client mode or WiFi Direct mode.

    Important Notes

    • To update a WiFi Shield's firmware it cannot be under control of an OpenBCI Board (Cyton or Ganglion). The WiFi needs to be powered independently, with Ganglion, WiFi Shield shall be disconnected, with Cyton, the EXT PWR shall be in the off position. Why? So the WiFi Shield can effectively power cycle.
    • If you have trouble joining the WiFi Shield network, turn the WiFi of your phone/computer/etc. off/on
    • It may take 10-15 seconds for your WiFi shield to appear in your WiFi options (be patient!)
    • Once you connect your WiFi shield to a network, it will no longer appear in your WiFi options with its "OpenBCI-XXXX" unique ID. To make it reappear, you must launch the WiFi manager (instructions below) or "Erase Credentials" of the WiFi Shield.
    • The WiFi shield does not work for Enterprise level security so use WiFi Direct mode or use your cellphone as a hot spot or set up your own wifi network.

    Configure WiFi Station Mode

    Follow this section if you want to put the WiFi Shield into WiFi Station mode. The WiFi Shield must be on the same wireless network as your computer, smart phone, or whatever other internet connected device you wish to talk to the WiFi Shield with. For example, in order to stream data into the OpenBCI GUI using your WiFi Shield in WiFi Station mode of operation, you must first make sure that your WiFi shield and computer that is running the OpenBCI GUI are on the same WiFi network.

    For the rest of this tutorial, the WiFi needs to be powered independently, with Ganglion, WiFi Shield shall be disconnected, with Cyton, the EXT PWR shall be in the off position.

    If you power the the WiFi Shield up and D2 LED does 4 blinks in 2 seconds followed within 10 seconds by 2 blinks in 2 seconds, then your WiFi Shield is on your local network. Feel free to head to skip a head to connecting with the OpenBCI GUI. If you want the WiFi Shield to join a different wireless network, continue reading and pay attention when it comes time to bring up the WiFi Manager.

    Before the WiFi Shield has joined a network, the Shield acts as a WiFi hotspot, where the D2 LED blinks 10 times in 2 seconds and will have a name such as "OpenBCI-A4AD" where the last four digits are hexadecimal and are unique to your WiFi Shield.

    To connect your WiFi shield to your local WiFi network (or any other WiFi network), use any WiFi-enabled device to connect to the WiFi shield hotspot. Once connected to the WiFi Shield's network go to http:. A link to go to the WiFi manager should then be clicked and you will be taken to the WiFi Manager page. Then you can scan for wireless networks and save your wireless network credentials. A captive touch portal as shown in the screenshots below may appear after hitting the endpoint, if so, continue on either page.

    Follow the below example that goes through the steps of connecting the WiFi Shield to a local WiFi networked called MeerkatManor. Note: in your case the network will not be called MeerkatManor but will instead be the name of whatever WiFi network you wish to connect your WiFi Shield to and share data across.

    WiFi Station Example

    Your local WiFi network is called MeerkatManor and it is password protected. You turn on the WiFi on your smartphone and search for WiFi network options. Additionally, your WiFi Shield is connected to a battery and powered on (and not connected to an OpenBCI Board, or if Cyton, EXT PWR is OFF). Note what the D2 light does at start-up, if your In your iPhone's WiFi network options, you see MeerkatManor and "OpenBCI-A4AD" (the last 4 characters will be different in your case).

    iPhone Connected to MeerkatManor

    You click "OpenBCI-A4AD", in an attempt to connect to the WiFi Shield's hotspot.

    iPhone Connecting to `OpenBCI-A4AD`

    Your phone or computer will connect to the WiFi Shield's hotspot.

    iPhone Connected to `OpenBCI-E218`

    Launch your web browser and navigate to to start the WiFi Manager.

    iPhone Web Browser

    A success page will load with a hyperlink to the WiFi Manager.

    iPhone wifi manager start request

    You will be rerouted to the now started WiFi Manager.

    WiFi Manager home page

    Click Configure WiFi to scan for nearby wireless networks or click Configure WiFi (No Scan) to enter the wireless network credentials. A captive touch portal may appear on the computer, phone or tablet, if so, continue the setup on the captive touch page if on mobile or ignore the portal on the computer if you want, either WiFi manager page will work!

    Captive touch portal first screen

    On the next screen, see that MeerkatManor is listed as a possible network for the WiFi Shield to join. Select MeerkatManor and enter the password for the network and press save.

    Captive touch portal second screen

    If the MeerkatManor password was entered correctly, then the WiFi Shield will join MeerkatManor after a quick reboot and every time the network is within range. Have fun streaming your brain waves over WiFi!

    Note: the OpenBCI WiFi shield cannot be paired with multiple WiFi networks. However, if the WiFi Shield is out of range of the network it is currently paired with, it will reappear as a hotspot again, you'll see the D2 light flash 10 times in 2 seconds. At this point, if you reconnect to the hotspot and then connect the WiFi Shield to a different WiFi network. The previous network credentials will be overwritten by the new ones.

    Captive touch portal final screen

    If you are a developer and want to control the WiFi Shield through HTTP commands checkout the WiFi Shield's web server specifications!

    Change Stored Credentials

    If your WiFi Shield blinks 4 times within 2 seconds followed by 2 blinks in 2 seconds then your WiFi Shield has an IP Address and is on a wireless network! If you want to change the credentials of the WiFi Shield, you must start the WiFi Manager or erase the stored wireless credentials. Using the WiFi Manager allows you to keep the WiFi Shield connected to an OpenBCI Board so the method is worth explaining. Erase the stored wireless credentials with a connected OpenBCI Board may not work because the OpenBCI Board will prevent the WiFi Shield from a required reset.

    Use a computer to join the same wireless network as the stored wireless network credentials on the WiFi Shield. Get the IP Address using from the wireless network it's currently attached to, you can get the IP address of the WiFi shield, and in a web browser visit to start the WiFi Manager.

    Now follow the example above for the WiFi Station Example to join the WiFi Shield's hotspot, use a web browser to go to and use the WiFi Manager to store the new wireless network credentials to flash memory.

    Erase Stored Credentials

    If the shield blinks four times within two seconds after power up, the WiFi Shield is searching for a wireless network that matches the wireless credentials stored in flash memory. If you see D2 LED blink 2 times in 2 seconds, then the WiFi Shield was successful in joining the wireless network matching the stored wireless network credentials in flash memory. If you see the D2 LED blink 10 times within 2 seconds, the WiFi Shield abandoned the search for a wireless network matching the wireless network credentials stored in flash memory.

    You must erase the stored credentials or else the WiFi Shield will spend 10 seconds searching for the wireless network matching the wireless network credentials stored in flash memory. Note that if you are out of range of the stored wireless network, the WiFi Shield will search for the wireless network, fail to find it after 10 seconds of searching and switch to WiFi Direct mode and visually show that to you by blinking D2 10 times in 2 seconds.

    There is a multitude of ways to erase stored wireless network configurations:

    1. Press "ERASE CREDENTIALS" of the WiFi Shield from the WIFI SHIELDS configuration inside the OpenBCI GUI. Make sure your WiFi Shield is not connected to an OpenBCI Board, or if Cyton, EXT PWR is OFF). Tutorial link here.
    2. On macOS/iPhone, go to your WiFi Shields home page in a web browser such as http://OpenBCI-A4AD.local (OpenBCI-A4AD is the name of the WiFi Shield) and tap "Click to Erase WiFi Credentials".
    3. On macOS/iOS, in a web browser go to http://OpenBCI-A4AD.local/wifi/delete (OpenBCI-A4AD is the name of the WiFi Shield).
    4. In any web browser on any device you can use the IP Address (OpenBCI GUI tutorial to get IP address) of the WiFi Shield and navigate to where the 192.168.1.100 is substituted for the WiFi Shield's IP Address to trigger the erase.
    • Send an HTTP DELETE request to 192.168.1.100/wifi where the 192.168.1.100 is the WiFi Shield's IP Address

    If you erase the WiFi Shield's stored credentials, the WiFi Shield will immediately startup in WiFi Direct mode and that's indicated with 10 blinks in 2 seconds.

    WiFi Direct Example

    You want to directly connect your computer with the WiFi Shield. Your WiFi Shield is connected to a battery and powered on. If D2 blinks 10 times in two seconds the shield is ready to go! If this is not the case, follow the example above to erase the stored wireless network credentials from flash memory.

    Connect your computer or phone to the WiFi Shield by joining the hotspot (a.k.a. wireless network, soft access point) broadcasted by the WiFi Shield.

    iPhone Connected to MeerkatManor

    Click "OpenBCI-A4AD", where your WiFi Shield is some other name such as OpenBCI-E318, in an attempt to connect to the WiFi Shield's hotspot.

    iPhone Connecting to `OpenBCI-A4AD`

    Your phone or computer will connect to the WiFi Shield's hotspot.

    iPhone Connected to `OpenBCI-E218`

    Launch your web browser and navigate to to go to your WiFi's home page.

    WiFi Shield home page on iPhone

    That's it! You're ready to stream high speed data from the WiFi Shield! You may use the OpenBCI GUI or any other interface such as NodeJS, python or many of the other new SDKs! Keep in mind the WiFi Shield's IP Address is set to 192.168.4.1.

    If you are a developer and want to control the WiFi Shield through HTTP commands checkout the server specifications!

    WiFi Configuration for Firmware 1.X.X

    Get the WiFi Shield On Your Wireless Network

    The WiFi Shield must be on the same wireless network as your computer, smart phone, or whatever other internet connected device you wish to talk to the WiFi Shield with. For example, in order to stream data into the OpenBCI GUI using your WiFi Shield, you must first make sure that your WiFi shield and computer that is running the OpenBCI GUI are on the same WiFi network.

    Before the WiFi Shield has joined a network, the Shield acts as a WiFi hotspot, and will have a name such as "OpenBCI-A4AD" where the last four digits are hexadecimal and are unique to your WiFi shield.

    To connect your WiFi shield to your local WiFi network (or any other WiFi network), use any WiFi-enabled device to connect to the WiFi shield hotspot. Doing this launches the captive touch portal as shown in the screenshots below. The captive touch portal is used to connect your WiFi shield to your local WiFi network (or any other WiFi network) so that it can share data across that network.

    Important Notes Before You Continue:

    • If you are able to join the WiFi network but a captive portal does not come up, use a web browser to go to http://192.168.4.1
    • In order to unpair your WiFi Shield with a WiFi network (or update its firmware), it cannot be under control of an OpenBCI Board (Cyton or Ganglion). It needs to be powered separately, with Ganglion, WiFi Shield shall be disconnected, with Cyton, the EXT PWR shall be in the off position. Why? So the WiFi Shield can effectively power cycle.
    • If you have trouble joining the WiFi Shield network, turn the WiFi of your phone/computer/etc. off/on
    • It may take 10-15 seconds for your WiFi shield to appear in your WiFi options (be patient!)
    • Once you connect your WiFi shield to a network, it will no longer appear in your WiFi options with its "OpenBCI-XXXX" unique ID. To make it reappear, you must first "ERASE CREDENTIALS" of the WiFi Shield from the WIFI SHIELDS configuration inside the OpenBCI GUI
    • The WiFi shield does not work for Enterprise level security. Use your cellphone as a hot spot or set up your own wifi network if this is an issue. Update to firmware v2.0.0 or later to use WiFi Direct as another alternative.

    Follow the below example that goes through the steps of connecting the WiFi Shield to a local WiFi networked called MeerkatManor. Note: in your case the network will not be called MeerkatManor but will instead be the name of whatever WiFi network you wish to connect your WiFi Shield to and share data across.

    Example

    Your local WiFi network is called MeerkatManor and it is password protected. You turn on the WiFi on your smartphone and search for WiFi network options. Additionally, your WiFi Shield is connected to a battery and powered on (and not connected to an OpenBCI Board!). In your iPhone's WiFi network options, you see MeerkatManor and "OpenBCI-A4AD" (the last 4 characters will be different in your case).

    iPhone Connected to MeerkatManor

    You click "OpenBCI-A4AD", in an attempt to launch the captive touch portal.

    Note: there is a known issue where it may take several times to bring up the captive touch portal. Push The World is actively seeking a better solution, in the meantime, be patient and try multiple times to connect to the board. Power cycling the board may useful.

    iPhone Connecting to `OpenBCI-A4AD`

    After a couple seconds a captive touch portal will appear on the computer, phone or tablet. Click Configure WiFi.

    Captive touch portal first screen

    On the next screen, see that MeerkatManor is listed as a possible network for the WiFi Shield to join. Select MeerkatManor and enter the password for the network and press save.

    Captive touch portal second screen

    If the MeerkatManor password was entered correctly, then the WiFi Shield will join MeerkatManor after a quick reboot and every time the network is within range. Have fun streaming your brain waves over WiFi!

    Note: the OpenBCI WiFi shield cannot be paired with multiple WiFi networks. However, if the WiFi Shield is out of range of the network it is currently paired with, it will reappear as a hotspot again. At this point, if you reconnect to the hotspot and then connect the WiFi Shield to a different WiFi network. The previous network credentials will be overwritten by the new ones.

    Captive touch portal final screen

    If you are a developer and want to control the WiFi Shield through HTTP commands checkout the server specifications!

    Connecting with the OpenBCI GUI

    Although the WiFi Shield can be connected to any internet connected device, the OpenBCI_GUI provides a great application to get started!

    Download/Install/Run the OpenBCI GUI

    The OpenBCI GUI gained WiFi Shield support as of v3.0.0 or later.

    Please follow the step by step guide to install the OpenBCI_GUI as a standalone application. WiFi has no other prerequisites.

    Come back to this guide when your GUI is running!

    Streaming Data On Cyton

    Select LIVE (from Cyton) from the first drop down

    selecting cyton from drop down

    Select Wifi (from WiFi Shield) as the transfer protocol

    selecting wifi from the transfer protocol

    The GUI will automatically start searching for WiFi Shields

    wifi with cyton searching for wifi shield

    Select the desired WiFi Shield from the dropdown list

    selecting wifi shield

    The Cyton will default to a sample rate of 1000Hz with a latency of 10ms. For the majority of modern data WiFi networks these settings will work. If your data transfer LED (D2 on WiFi Shield) is not solid blue, then you should try adjusting your sample rate and latency while you determine your wireless network problems.

    setting latency and sample rate of cyton

    Press START SYSTEM when you're ready to begin streaming.

    wifi cyton start system

    Press Start Data Stream to begin streaming!

    cyton wifi starting data stream

    When you are finished recording, you may press Stop Data Stream

    cyton wifi stopping data stream

    Then end your session by pressing STOP SYSTEM from the System Control Panel drop down.

    cyton wifi stop system

    If you are unable to connect to the board

    1. Verify the EXT PWR switch is in the ON position.
    2. Verify you do not have a battery in the Cyton
    3. Verify the latest firmware on the Cyton
    4. Verify the latest firmware on the WiFi Shield

    Streaming Data On Ganglion

    Select LIVE (from Ganglion) from the first drop down

    selecting ganglion from drop down

    Select Wifi (from WiFi Shield) as the transfer protocol

    selecting wifi from the transfer protocol

    The GUI will automatically start searching for WiFi Shields

    wifi with ganglion searching for wifi shield

    Select the desired WiFi Shield from the dropdown list

    selecting wifi shield

    The Ganglion will default to a sample rate of 1600Hz with a latency of 10ms. For the majority of modern data WiFi networks these settings will work. If your data transfer LED (D2 on WiFi Shield) is not solid blue, then you should try adjusting your sample rate and latency while you determine your wireless network problems.

    setting latency and sample rate of ganglion

    Press START SYSTEM when you're ready to begin streaming.

    wifi ganglion start system

    Press Start Data Stream to begin streaming!

    ganglion wifi starting data stream

    When you are finished recording, you may press Stop Data Stream

    ganglion wifi stopping data stream

    Then end your session by pressing STOP SYSTEM from the System Control Panel drop down.

    ganglion wifi stop system

    If you are unable to connect to the board

    1. Verify all three LEDs on the WiFi Shield are solid on.
    2. If using the Ganglion to power the WiFi Shield, verify the EXT PWR switch is in the ON position.
    3. If using two batteries, verify the EXT PWR switch is in the OFF position and be sure to always turn the WiFi Shield on before the Ganglion.
    4. Verify the latest firmware on the Ganglion
    5. Verify the latest firmware on the WiFi Shield

    Get WiFi Shield IP, Mac Address, Firmware Version and more

    Select LIVE (from Ganglion) or LIVE (from Cyton) from the first drop down

    selecting ganglion from drop down

    Select Wifi (from WiFi Shield) as the transfer protocol

    selecting wifi from the transfer protocol

    The GUI will automatically start searching for WiFi Shields

    wifi with ganglion searching for wifi shield

    Select the desired WiFi Shield from the dropdown list

    selecting wifi shield

    Select the right carrot button to open the WiFi Configuration window

    selecting right carrot to open wifi config

    If the connection to the WiFi Shield was successful, you will see a success message.

    success connection to wifi shield

    When you are finished, press the left facing caret to close the WiFi Configuration window.

    selecting left facing arrow to close wifi configuration

    Get WiFi Shield Firmware Version

    To verify you have the latest OpenBCI_Wifi firmware version, select FIRMWARE VERSION from the WiFi Configuration menu

    selecting firmware version for wifi

    Compare the firmware version with the latest OpenBCI_Wifi firmware available and download/update your firmware if it's outdated.

    Get WiFi Shield IP Address

    To get the Wifi Shield IP Address, select IP ADDRESS from the WiFi Configuration menu

    getting ip address for openbci wifi shield

    Get WiFi Shield Mac Address

    To get the Wifi Shield IP Address, select MAC ADDRESS from the WiFi Configuration menu

    getting mac address for openbci wifi shield

    What OpenBCI Board is Connected to the Wifi Shield

    If you are having trouble starting to stream with the GUI, then select OPENBCI BOARD to verify the WiFi Shield is attached properly to the Cyton or Ganglion.

    getting connected openbci board

    Erase WiFi Credentials

    If you want to switch what WiFi network your WiFi Shield is on, you can select ERASE CREDENTIALS. NOTE: WiFi Shield must be detached from Ganglion or Cyton.

    erase credentials for openbci wifi shield

    The GUI will automatically detach from the WiFi Shield. Your WiFi Shield should now be a hotspot which you can join to give the WiFi Shield the credentials for the new network.

    erase credentials force close

    Before we jump into setting up your WiFi Shield, here are some helpful links:

    - - + + \ No newline at end of file diff --git a/GettingStarted/Community/Community/index.html b/GettingStarted/Community/Community/index.html index e1c3f2ec0..f64458a9b 100644 --- a/GettingStarted/Community/Community/index.html +++ b/GettingStarted/Community/Community/index.html @@ -12,13 +12,13 @@ Welcome to the OpenBCI Community | OpenBCI Documentation - - + +
    Skip to main content

    Welcome to the OpenBCI Community

    openbci.com/community/

    Thank you! You represent the heart of OpenBCI. Without your support and belief in the OpenBCI mission, we wouldn't be where we are today.

    The OpenBCI Community interface is our latest project. It consists of:

    • The People - you! The people making posts and creating challenges
    • The Feed - where new community posts end up
    • Join - the way to register (send this to your friends)!

    After you register and are verified (we must approve your application), your account will be switched from subscriber to contributor. After this, you'll be able to create posts and challenges! Posts appear in the Community Feed, and challenges appear on the Challenges Page. More on this below.

    Editing Your Profile

    Upon registering, you should have received an email with your Login/Password. If you did not, reach out to me and Iโ€™ll help you recover it. To edit your profile:

    1. Go to the OpenBCI Wordpress login & enter your Login/Password
    • Navigate to โ€œProfileโ€ on the left-hand side of the admin page
    • Add any missing information
    • Click the โ€œSaveโ€ button to confirm

    Note: your profile will not appear on the People Page until you have a first name, last name, and photo. All other info is optional (but encouraged)!

    Once you have made an account, reach out to contact@openbci.com. Your account is inactive until an admin "checks off" your account. Weโ€™ll make sure your profile is active and set up as a contributor.

    Making Posts

    Making a post is a great way to share a cool project, tutorial, or research study that youโ€™ve completed. In general, a post should be something finished (a hack, a lesson, a research study with findings, etc.).

    Our community page is based on the Wordpress platform. If youโ€™ve used Wordpress before, youโ€™ll feel right at home. If not, no worriesโ€”itโ€™s easy! Log in the same way you would to edit your profile. When you log in, the Wordpress admin page should appear with an option to see the Posts section. Click on it and select Add New from the menu. Next, follow this great tutorial on how to write a Wordpress post. You are now ready to start sharing your work!

    On The Horizon

    The OpenBCI Community interface will be forever under development. We really want your feedback! If you have suggestions, please email contact@openbci.com.

    As we move forward, we want to improve the level of interactivity between community members and also provide incentives for posting cool projects and challenges.

    In addition, we are thinking about ways to enable you to request and share biodata with other members of the OpenBCI Community. Of course the priority will always be that all data exchanged in this way belongs to the individual who generates the data (first and foremost) and will remain open for others access.

    Final Note

    The OpenBCI Community is only as strong as its members. We are calling upon you (!) to help us push the OpenBCI mission forward by collaborating with each other and going the extra step to share the work that you do. The more we all contribute and collaborate, the more the community benefits as a whole! Let's see what we can build together!

    - - + + \ No newline at end of file diff --git a/GettingStarted/Documentation/DocEdits/index.html b/GettingStarted/Documentation/DocEdits/index.html index 04237761d..14f8cddb3 100644 --- a/GettingStarted/Documentation/DocEdits/index.html +++ b/GettingStarted/Documentation/DocEdits/index.html @@ -12,13 +12,13 @@ Editing Docs Guide | OpenBCI Documentation - - + +
    Skip to main content

    Editing Docs Guide

    This page will explain the process of contributing to the OpenBCI documentation.

    Minor Changes

    If you'd like to make a minor change to our docs, such as updating a hyperlink or fixing a typo, all you need to do is:

    1. Find the page you want to edit and scroll to the bottom
    2. Click on the Edit this page button. You'll be redirected to your Github account.
    3. Github will ask you to fork our repository. Click on Fork this repository.
    4. Make the changes.
    5. Click on Propose changes.
    6. Done. Your changes will be reviewed by our admins!

    Major Changes

    If you'd like to make a major change, such as adding a new document, follow the steps on our Docs Wiki.

    - - + + \ No newline at end of file diff --git a/GettingStarted/GettingStartedLanding/index.html b/GettingStarted/GettingStartedLanding/index.html index f99b21d43..bcf9692c8 100644 --- a/GettingStarted/GettingStartedLanding/index.html +++ b/GettingStarted/GettingStartedLanding/index.html @@ -12,13 +12,13 @@ Getting Started | OpenBCI Documentation - - + +
    Skip to main content

    Getting Started

    This directory will show you everything you need to know to get started with OpenBCI.

    Boards

    This section will run through the setup of each of our boards, and how to begin using them. Pages in this section include:

    Biosensing Setups

    This section details the electrode setups for the various types of biosensing:

    • EEG Setup โ€” Details how to wire electrodes to gather signals from the brain.
    • EMG Setup โ€” Details how to wire electrodes to gather signals from different muscle groups.
    • ECG Setup โ€” Details how to wire electrodes to gather signals from different muscle groups.

    Community

    This section contains the tutorial about getting started as a member of the OpenBCI Community:

    - - + + \ No newline at end of file diff --git a/Software/CompatibleThirdPartySoftware/BioEra/index.html b/Software/CompatibleThirdPartySoftware/BioEra/index.html index baa52fe80..e824384bd 100644 --- a/Software/CompatibleThirdPartySoftware/BioEra/index.html +++ b/Software/CompatibleThirdPartySoftware/BioEra/index.html @@ -12,13 +12,13 @@ BioEra | OpenBCI Documentation - - + +
    Skip to main content

    BioEra

    From the BioEra homepage: BioEra is a visual designer useful for analyzing signals in real time. It can be used with any device with ability to stream data to a computer.

    BioEra is used to create a design visually. A design represents data flow from input (e.g. biofeedback device) to output (e.g. visual or sound feedback). The flow can be customized with hundreds built-in objects (elements). For example an amplitude of alpha brainwaves can be filtered from input EEG signal, it can then trigger a MIDI, video or a computer task at a certain threshold level.

    Setting Up Your Environment

    Windows: BioEra only works with Windows and Android systems.

    MacOS and Linux: If you have Mac OS or Linux, you can use BioEra through a virtual machine program like VirtualBox. Check out our VirtualBox tutorial here!

    Installation

    Click on the download link for the trial version of BioEra here: (http:). If you're using a virtual machine, be sure to download and set up BioEra from within the VM environment.

    Click BioEra Trial 4.027 for Windows - full, or the equivalent link for the latest version, and follow the prompts to run the program.

    During installation, you may get an error that your computer or virtual machine has the incorrect processor for the program; just disregard the warning and continue with the installation.

    Getting Started

    Once installation is complete, navigate to the new "BioEraTrial" folder and double-click the "bioera" executable file. This will run BioEra.

    A PacMan demo will pop up automatically. Play around with the demo, or take a look at the BioEra website, to learn more about the software's capabilites.

    Streaming from OpenBCI within BioEra

    This section will show how to stream data live from your OpenBCI board within BioEra. We'll also show how to use the oscilloscope tool, as an introduction to BioEra's interface, as well as a way to verify your board is streaming data to BioEra.

    Start BioEra. To start a new project, select System -> New Design from the toolbar of one of the windows.

    Two new windows will appear - one with a light gray background (the "design" window) and one with a dark gray background (the "output" window). In the design window, select Element -> New.

    In the New Element window, find the "FTDI Serial Port" object. Select it and click "OK".

    An FTDI icon should now be visible in the design window.

    Navigate to Element -> New again from the toolbar. Find the "OpenBCI" object. Select it and click "OK". An OpenBCI icon should now be visible in the design window.

    Connect the output of the FTDI object with the input of the OpenBCI object, as shown. To connect the two objects, click on the output of the FTDI object, the click on the input of the OpenBCI object.

    You're ready to stream live data from your OpenBCI board! In the next section, we'll give an example for how to use and display your OpenBCI data using BioEra tools.

    Quick Project: Using the Oscilloscoope Tool

    BioEra has a wide variety of useful tools for streaming EEG data. To get familiar with BioEraโ€™s interface, and to double-check our board is streaming data, weโ€™ll show how to use the oscilloscope tool. An oscilloscope is a tool that displays changes in signal voltage vs. time (just like the main display of the OpenBCI GUI).

    Select an oscilloscope object the same way you selected the FTDI and OpenBCI objects. In addition to the oscilloscope icon in the design window, an oscilloscope display will appear in the dark grey window, like below. Connect one of the OpenBCI channels to the oscilloscope icon input.

    Select the "View" button at the top of the design window. The oscilloscope screen should look like below.

    Press the "play" button at the top of the design window. Data will start streaming from your board into BioEra (BioEra should automatically identify your board's serial port). A red light should appear on the OpenBCI Dongle; this means data is streaming from your OpenBCI board to your computer.

    Tap on the pins of your OpenBCI board. You should see the oscilloscope signal react accordingly.

    You are now streaming live data from your OpenBCI board into BioEra! Check out the rest of BioEra's tools for EEG streaming and processing.

    Documentation

    To learn more about BioEra, look through their manual or forum.

    Build something new using BioEra and OpenBCI hardware? Post about it on our community page!

    - - + + \ No newline at end of file diff --git a/Software/CompatibleThirdPartySoftware/BrainBay/index.html b/Software/CompatibleThirdPartySoftware/BrainBay/index.html index e833ac2e5..19591a976 100644 --- a/Software/CompatibleThirdPartySoftware/BrainBay/index.html +++ b/Software/CompatibleThirdPartySoftware/BrainBay/index.html @@ -12,13 +12,13 @@ BrainBay | OpenBCI Documentation - - + +
    Skip to main content

    BrainBay

    From their OpenBCI tutorials page: BrainBay is an open-source visual programming language (VPL) for rapid prototyping of EEG digital signal processing steps (or data flows.)

    They recently added an OpenBCI driver to their software, making it easy to use BrainBay with OpenBCI products!

    Setting Up Your Environment

    Windows: BrainBay only works with the Windows operating system.

    MacOS and Linux: If you have Mac OS or Linux, you can use BrainBay through a virtual machine program like VirtualBox. Check out our VirtualBox tutorial here!

    Installation

    Click on the download link for the lastest version of BrainBay here: (http:). If you're using a virtual machine, be sure to download and set up BrainBay from within the VM environment.

    Click Setup_BrainBay_v2.1.exe, or the equivalent .exe for the latest version, and follow the prompts to run the program. When you're finished, a BrainBay icon should appear on your desktop.

    Getting Started

    Double-clicking the BrainBay icon will open a demo screen. To learn more about BrainBay's capabilities, click on one of the demo options.

    To begin using BrainBay yourself, click on Design -> New from the toolbar at the top of the screen.

    You're now ready to use BrainBay for EEG streaming and analysis!

    Importing data from OpenBCI to BrainBay

    BrainBay does have an "import data from file" option, but it is only compatible with archive (.arc) files. The OpenBCI GUI saves data as comma-delineated .txt files. So, unless you have another application that saves data from your OpenBCI board as .arc files, you need to stream data live to use BrainBay.

    Live Stream from OpenBCI to BrainBay

    To stream data live from your OpenBCI board within a BrainBay design, select Insert Element -> Source -> Biosignal/EEG Amplifier and one of the OpenBCI devices. I'm using a Cyton board (without the Daisy extension), so I selected "OpenBCI 8 Channels".

    After selecting your device, an EEG window will appear. Select your device's COM port. If you're using VirtualBox, our VirtualBox tutorial has a section on finding the COM port of a connected hardware device.

    Click "Connect/Disconnect". A checkmark should appear in the "connected:" box.

    Exit out of the device configuration window. A icon corresponding to your OpenBCI board should have appeared in your design window, like below. Re-open the configuration window at any time by right-clicking on the icon.

    You're now streaming data from your board! In the next section, we'll show a simple example of how to use and display your OpenBCI data using BrainBay tools.

    Quick Project: Using the Oscilloscope Tool

    BrainBay has a wide variety of useful tools for streaming EEG data. To get familiar with BrainBay's interface, and to double-check our board is streaming data, we'll show how to use the oscilloscope tool. An oscilloscope is a tool that displays changes in signal voltage vs. time (just like the main display of the OpenBCI GUI).

    Select Insert Element -> Target -> Oscilloscope from the toolbar.

    A icon representing the oscilloscope will appear in the "Design" window. Drag it off the icon representing your OpenBCI board if necessary.

    A second window will pop up behind your design window. This window will display the oscilloscope output. Reposition the Design and Oscilloscope windows so both are visible.

    Click on the "Design" window. Click on the icon for the Cyton board, so that it's outlined in yellow. Decide which input channel (or which Cyton board pin) you want to display on the oscilloscope. Click and hold on the orange circle next to that channel. Drag the cursor to the yellow "chan1" circle on the oscilloscope icon. A red line should now connect the two circles.

    Press the "Play (F7)" button at the bottom of the BrainBay screen. A red LED on your Dongle should turn on. This means your board is streaming live data to your computer!

    Tap on the pins of your OpenBCI Cyton board. You should see a signal response in the oscilloscope window.

    You are now using BrainBay to view data streamed from your OpenBCI board! Feel free to connect one of the other OpenBCI channels to "chan2" on the oscilloscope icon to view signals from multiple pins at once. Once you're comfortable with the oscilloscope tool, explore BrainBay's other target and processing tools!

    Want to learn more about BrainBay's capabilities with OpenBCI hardware? Check out their BrainBay & OpenBCI tutorials page.

    Documentation

    Documentation for the BrainBay software can be found here: ()

    Did you use BrainBay and OpenBCI to build something new? Post about it on our community page!

    - - + + \ No newline at end of file diff --git a/Software/CompatibleThirdPartySoftware/LSL/index.html b/Software/CompatibleThirdPartySoftware/LSL/index.html index b6454b1d2..854d0579b 100644 --- a/Software/CompatibleThirdPartySoftware/LSL/index.html +++ b/Software/CompatibleThirdPartySoftware/LSL/index.html @@ -12,8 +12,8 @@ Lab Streaming Layer (LSL) | OpenBCI Documentation - - + +
    @@ -21,7 +21,7 @@ Python might already be installed on your computer. Type python --version to check if you have Python version 2 or 3 installed.
  • Install Python requirements To use this program, you need the following Python packages installed:
  • To automatically install using pip, navigate to the "OpenBCI_LSL" folder on your command line and terminal, and type:


    pip install -r requirements.txt

    Note: pip may have issues install numpy and scipy for some users. Install these manually if you have issues.

    Note: If you get the message "pip: command not found", you need to install pip: sudo easy_install pip. Then retry the command above.

    To use the GUI features of this application, you must separately install PyQt4 using these instructions: Install PyQt4. The command line version of this program is still functional if PyQt4 is not installed.

    Usage

    Simple Stream

    First, make sure your dongle is plugged in and board is powered on. Then go the the "OpenBCI_LSL" folder and type the following command:


    python openbci_lsl.py --stream

    After a few moments, you should see this output:

    If an error is raised about not being able to find your the board or serial port, you can override the automatic board detection by specifying the serial port in a command line argument before "--stream". The format is as follows:


    python openbci_lsl.py [PORT] --stream

    For example:


    python openbci_lsl.py /dev/ttyUSB0 --stream

    After board initialization, you are now ready to start streaming.

    To begin streaming, type /start

    To stop streaming, type /stop

    To disconnect from the serial port, type /exit

    Remember to use /exit to disconnect the board as you end the program, to ensure that the serial port is safely closed.

    Configuring the board from the command line interface

    You also configure board settings from this interface. For full information regarding board settings and commands, see the Cyton board programming tutorial.

    To enter Channel Settings mode, you would need to enter an "x", followed by certain channel settings, followed by an "X". For example:


    x3020000X

    This command will do the following: โ€˜xโ€™ enters Channel Settings mode. Channel 3 is set up to be powered up, with gain of 2, normal input, removed from BIAS generation, removed from SRB2, removed from SRB1. The final โ€˜Xโ€™ latches the settings to the ADS1299 channel settings register.

    To view current board and register settings, enter: ?

    If you get an error message at any point while using the command line interface, check the Troubleshooting section, or pull up an issue on the Github repository.

    Changing Channel Locations from the command line interface To change the channel location metadata of the stream, type /loc followed by a space and then a comma-separated list of new set of channel locations. For example, to change the default channel locations to a new set of eight channels, the command might look like this:


    /loc F3,F4,C3,C4,T3,T4,P3,P4

    This can only be done while the board is not currently streaming.

    GUI

    If you would like the ability to configure the board and LSL stream with advanced settings, you can do so by running the GUI. The GUI comes up by default if you run the program with no flags:

    python openbci_lsl.py

    If you plug in your board and dongle before running the above command, the program should have already detected the appropriate settings for your board (port and daisy). If not, you can enter those yourself in the appropriate fields.

    Streaming

    To stream data, make sure the appropriate Port, Daisy, and LSL Stream fields are filled in correctly. Then, press "Connect" and then "Start Streaming". To pause streaming, click "Stop Streaming". To disconnect the board, press "Disconnect".

    The board must be disconnected to change LSL settings. Once you "Connect" again, your current settings are saved until the next time you disconnect.

    For consistent performance, pause streaming before you disconnect the board.

    Configuring the board from the GUI

    To change the channel settings, click on "Board Config". Note: this must be done BEFORE you press "Connect".

    Troubleshooting

    Note: Many issues with board connectivity can simply be resolved by restarting the program and your board. Unplug your dongle, turn off the board, plug in the dongle, and turn on the board, in that order. This method works the most consistently.

    Next Steps

    Once you have the Lab Streaming Layer set up with your OpenBCI board, check out these other tutorials to view the stream in a variety of different programs:

    Matlab tutorial

    Credit

    Thanks to Winslow Strong for posting the original tutorial on the OpenBCI forums!

    - - + + \ No newline at end of file diff --git a/Software/CompatibleThirdPartySoftware/Matlab/index.html b/Software/CompatibleThirdPartySoftware/Matlab/index.html index e46745e07..3335466de 100644 --- a/Software/CompatibleThirdPartySoftware/Matlab/index.html +++ b/Software/CompatibleThirdPartySoftware/Matlab/index.html @@ -12,14 +12,14 @@ MATLAB | OpenBCI Documentation - - + +
    Skip to main content

    MATLAB

    MATLAB is a powerful numerical computing language and environment that is widely used in a wide variety of academic, research, and industrial applications.

    A few MATLAB toolboxes have been created specifically for working with EEG and BCI. EEGLAB, BCILAB, ERPLAB, and FieldTrip are a few toolboxes that have helped OpenBCI users work in MATLAB.

    This tutorial will walk through setting up your MATLAB environment for use with OpenBCI hardware, as well as some basic uses and functionalities that MATLAB offers for working with brain-computer interfaces.

    Installation

    Go to the MathWorks website for MATLAB installation instructions.

    info

    Please note that MATLAB is commercial software. Licenses must either be purchased or acquired through academic or professional institutions.

    Several useful MATLAB toolkits (EEGLAB, BCILAB, FieldTrip, etc) have been created for collecting and analyzing EEG data, so this tutorial will focus on using MATLAB through these toolkits.

    There are two main ways to get your OpenBCI data while leveraging BrainFlow. The first method is to connect directly using the BrainFlow MATLAB Binding to get live data, and the second is to use a BrainFlow CSV file and BrainFlow Playback Board for offline playback or analysis.

    BrainFlow Slack

    For more in-depth questions and assistance with BrainFlow, please visit the official BrainFlow Slack.

    Method 1: Live Data Directly from OpenBCI Board using BrainFlow

    Now that we can connect to OpenBCI boards using BrainFlow, we can utilize the MATLAB binding to get direct access without using LSL.

    Code Examples

    Here are the official code examples of how to connect to OpenBCI boards directly in MATLAB.

    Method 2: Offline data playback using BrainFlow CSV file and Playback Board

    Use OpenBCI GUI to create BrainFlow CSV File

    See the screenshot below to see where the option is to save data to BrainFlow CSV file. This is enabled by default and is saved simultaneously alongside OpenBCI CSV data in [USER]/Documents/OpenBCI_GUI/Recordings. You can then load this file into MATLAB.

    BrainFlow Streamer Control Panel - Save to File

    OpenBCI vs. BrainFlow CSV

    This method is not the same as using OpenBCI CSV files. In BrainFlow CSV files, data stored is in a slightly different order and configuration.

    • BrainFlow CSV File Example: BrainFlow-RAW_2022-03-11_15-41-42_0.csv
    • OpenBCI CSV File Example: OpenBCI-RAW-2022-03-11_15-44-27.txt

    Use BrainFlow Python Script to Read/Write BrainFlow CSV File

    Here is the code sample to read/write BrainFlow CSV file using BrainFlow Python Binding

    Using the OpenBCI GUI

    Method 1: Offline Import of CSV file from the OpenBCI GUI

    To get started, use your OpenBCI board (like the Cyton or Ganglion board) and the OpenBCI GUI to stream some data. Whenever you stream data to the GUI, it's also automatically saved in .csv format on your computer. GUI recordings are saved to [USER]/Documents/OpenBCI_GUI/Recordings/ on all operating systems. The OpenBCI Processing GUI saves data in text (txt) or comma-separated value (CSV) files.

    OpenBCI vs. BrainFlow CSV

    This method is not the same as using BrainFlow CSV files. In OpenBCI CSV files, data stored is in a slightly different order and configuration.

    • BrainFlow CSV File Example: BrainFlow-RAW_2022-03-11_15-41-42_0.csv
    • OpenBCI CSV File Example: OpenBCI-RAW-2022-03-11_15-44-27.txt

    Import the CSV file into MATLAB as a matrix by using the "Import Data" wizard:

    Select a saved OpenBCI data file. Once the data import screen is open, select the "Numeric Matrix" import option. Deselect all of the header rows. Also deselect the final column, the timestamp values, since the import wizard can only parse numeric values. Feel free to give your matrix a convenient name, like "eeg_data":

    Click "Import Selection". Your matrix should now appear as an object in your workspace! Keep reading to learn more about processing your data with MATLAB toolboxes.

    Method 2: Stream Live Time Series Data from the OpenBCI GUI via LSL

    You can also stream live OpenBCI data into MATLAB using the Lab Streaming Layer either from the OpenBCI GUI or from Python. Here, we will go over how to import data from the OpenBCI GUI.

    Open the OpenBCI GUI and "Start System" with your setup as you would do. On the widget dropdown menu, select "Networking". At the right upper corner of the Networking widget, there is another dropdown menu. Select "LSL."

    Now you can select the OpenBCI Data you want to send, the Name of the LSL stream, the data advertised by the LSL, and the number of channels you will be sending. Once you select your parameters make sure to turn on your LSL stream at the bottom of the widget. Then click start and you are ready to go.

    Import the LSL stream into MATLAB

    There are two ways to import an LSL using the liblsl-Matlab library to stream into MATLAB or using the BCILAB toolbox.

    liblsl-Matlab

    Follow the installation instructions on the liblsb-Matlab GitHub Repo. Once you successfully added the correct directories and files you can use the following script to stream the OpenBCI data from your LSL stream.


    %% instantiate the library
    disp('Loading the library...');
    lib = lsl_loadlib();

    % resolve a stream...
    disp('Resolving an EEG stream...');
    result = {};
    while isempty(result)
    result = lsl_resolve_byprop(lib,'type','EEG'); end

    % create a new inlet
    disp('Opening an inlet...');
    inlet = lsl_inlet(result{1});

    disp('Now receiving data...');
    while true
    % get data from the inlet
    [vec,ts] = inlet.pull_sample();
    % and display it
    fprintf('%.2f\t',vec);
    fprintf('%.5f\n',ts);
    end

    BCILAB

    From the BCILAB wiki: "BCILAB is a MATLAB toolbox and EEGLAB plugin for the design, prototyping, testing, experimentation with, and evaluation of Brain-Computer Interfaces (BCIs), and other systems in the same computational framework."

    BCILAB provides a GUI from which you can control the plugin, but batch scripting can be used for those well-versed in MATLAB programming.

    Installation

    To install BCILAB, download the development version of BCILAB and extract it to any directory that is not your EEGLAB folder. Note: I found that the non-developer version (found here) had bugs that were fixed by using the BCILAB-devel version instead.

    Open up MATLAB, and set your current MATLAB directory to the unzipped BCILAB file:


    cd your/path/to/bcilab;

    Once you're in the file, just type the command:


    bcilab

    Import LSL

    To start running BCILAB. After some console output, you should see the text "Welcome to the BCILAB toolbox!" and then a new GUI with the BCILAB menu should appear.

    Once a stream has been started on your computer, open BCILAB within MATLAB (>> cd your/path/to/bcilab; bcilab) and from the menu, select Online Analysis > Read input from... > Lab streaming layer...

    Analyzing OpenBCI data

    There are many ways in which you can use MATLAB to analyze the data from the OpenBCI board, we will go over a few common ones to get started.

    EEGLAB

    From the EEGLAB wiki: "EEGLAB is an interactive MATLAB toolbox for processing continuous and event-related EEG, MEG and other electrophysiological data using independent component analysis (ICA), time/frequency analysis, and other methods including artifact rejection."

    Setup

    Go to the EEGLAB downloads page and follow the instructions for your operating system.

    Download the zip file of the most current version of EEGLAB and extract it into a directory on your system. Then, make this toolbox accessible from MATLAB by adding a path to this directory (the steps to do this vary by OS - see the "EEGLAB downloads page" link above).

    To check if EEGLAB is correctly set up, go to the MATLAB prompt and type:

    >> eeglab

    If the toolkit is not yet correctly implemented, the console should output: "Undefined function or variable 'eeglab'."

    If it is set up correctly, a pop-up window should appear with the EEGLAB GUI.

    Preparing OpenBCI Datasets for EEGLAB Use

    OpenBCI saves data in the opposite orientation from what EEGLAB needs. So, after importing your OpenBCI data to MATLAB as described above, perform a simple matrix transposition:


    eeg_data = eeg_data'

    Your data matrix is now ready to use with EEGLAB.

    Using EEGLAB

    If EEGLAB isn't already running, enter "eeglab" into the MATLAB command line to start the program. Import your matrix into EEGLAB using the EEGLAB GUI: File -> Import Data -> Using EEGLAB functions and plugins -> From ASCII/float file or MATLAB array

    In the pop-up window that appears, enter information about the data set. Select "MATLAB variable", and enter the name of the variable where your matrix is stored. Enter the Data Sampling rate (it should be commented in at the top of the text file - usually 250 Hz by default in the OpenBCI GUI). The other fields can be left at default, and EEGLAB will automatically fill in the information from the data set.

    Channel locations are useful for plotting EEG scalp maps in 2-D or 3-D format. OpenBCI uses the standard 10-20 format for the 8 and 16 channel models, which can be found within these sfp files: 8 channel and 16 channel. You can then import channel data by click "Browse" next to "Channel location file or info" and locating the OpenBCI sfp file you downloaded.

    The data is now imported into EEGLAB and ready to use!

    Plotting Data in EEGLAB

    To double-check your data is imported correctly, and to get familiar with EEGLAB's interface, try plotting your data. Select Plot -> Channel data (scroll) from the EEGLAB pop-up window.

    Your data should appear in a window like the image below:

    Check out the links in the Further Reading section to learn more about processing data with EEGLAB!

    Streaming into EEGLAB

    From what we can tell, EEGLAB seems to work primarily with datasets and recorded data.

    ERPLAB

    From the ERPLAB homepage: "ERPLAB Toolbox is a free, open-source MATLAB package for analyzing ERP data. It is tightly integrated with EEGLAB Toolbox, extending EEGLABโ€™s capabilities to provide robust, industrial-strength tools for ERP processing, visualization, and analysis. A graphical user interface makes it easy for beginners to learn, and MATLAB scripting provides enormous power for intermediate and advanced users."

    Setup

    Download and extract the latest ERPLAB release to the "plugins" folder of your EEGLAB directory (if you have an old release of EEGLAB, you will also have to enter the path to this directory in MATLAB by File > Set Path)

    Next time your launch EEGLAB, the ERPLAB menu should appear in the EEGLAB GUI:

    Analyzing EEG Data Sets

    To use ERPLAB for analyzing EEG datasets, import your data set as seen in the [Using EEGLAB Section](#Using EEGLAB). After the EEG data is imported into EEGLAB, you can then use ERPLAB functions to analyze your data. Read more on using ERPLAB on their website

    FieldTrip

    From the FieldTrip homepage: "The toolbox offers advanced analysis methods of MEG, EEG, and invasive electrophysiological data, such as time-frequency analysis, source reconstruction using dipoles, distributed sources and beamformers and non-parametric statistical testing."

    Setup

    Download the latest version of FieldTrip from the download page (you will have to provide an email address and description of research).

    Add the FieldTrip directory to your MATLAB path and check out FieldTrip's getting started guide.

    Further Reading

    EEGLAB Wiki

    BCILAB Wiki

    ERPLAB Homepage and ERPLAB Original Publication in Frontiers in Human Neuroscience.

    FieldTrip Homepage

    - - + + \ No newline at end of file diff --git a/Software/CompatibleThirdPartySoftware/Neuromore/index.html b/Software/CompatibleThirdPartySoftware/Neuromore/index.html index 89805c249..1f4e06784 100644 --- a/Software/CompatibleThirdPartySoftware/Neuromore/index.html +++ b/Software/CompatibleThirdPartySoftware/Neuromore/index.html @@ -12,13 +12,13 @@ Neuromore | OpenBCI Documentation - - + +
    Skip to main content

    Neuromore

    Neuromore is an EEG streaming and processing studio. Like BrainBay and BioEra, it provides a visual designer that can be used to process signals real-time.

    Setting Up Your Environment

    Windows: Neuromore Studio is available for Windows (but only as a 64-bit application).

    OS X: Neuromore Studio is available for MacOS, but see the FTDI OS X fix before using it.

    Linux: If you have Linux, you can use Neuromore through a virtual machine program like VirtualBox. Check out our VirtualBox tutorial here! See FTDI Linux Fix.

    Installation

    Download the latest verison of Neuromore Studio for your operating system from their website. After installation, the application will be in the folder neuromore -> Studio.

    Getting Started

    Open the Neuromore Studio application. A demo will begin playing that displays example EEG data.

    Livestream from OpenBCI to Neuromore

    First, connect your OpenBCI board to your computer. Make sure to take the following steps:

    Windows: Make sure your board is recognized as a COM port and that its latency is set to 1 ms. To troubleshoot, read our OpenBCI on Windows tutorial.

    OS X: Make sure your board is connected and visible as a device. To check you can type ls /dev/tty.* on your terminal. An example connected OBCI board should like like this:


    Rodrigos-MacBook-Pro:~ rodrigo$ ls /dev/tty.*
    /dev/tty.OpenBCI-DN00959R

    Now, to connect to your OpenBCI board from within Neuromore, click the magnifying glass under "Devices" in the top right corner. This will prompt Neuromore to search for new devices. You should see an OpenBCI logo pop up, and data from your board will start streaming in the top of the Neuromore window.

    Troubleshooting

    Neuromore is pretty awesome in terms of board connectivity. If you open up the studio and connect your board, 9 out of 10 times it'll automatically connect.

    If it doesn't, try the following:

    1. Reset OBCI Board (Press Reset Button).
    2. Turn OBCI Board OFF, disconnect dongle, reconnect dongle, turn board back ON.
    3. Close neuromore and disconnect board and dongle. Connect Dongle and Board again and then open neuromore Studio.

    NOTE: If your board is connected properly, neuromore should have no trouble connecting to it.

    Getting Started

    To get started with Neuromore, open the "Getting Started" classifier in the OpenBCI folder of the "Back-End File System" pane:

    An example of Neuromore's visual programming language will appear. Click the wrench-and-screwdriver icon to hide the Node Palette pane if necessary.

    Neuromore calls these graphs of interconnected processing units "Classifiers". The basic structure of a classifer consists of a input device (such as OpenBCI V3) connected to processing nodes that end in some sort of output node.

    Some of the output nodes produce visual output, like graphs in the time or frequency domain. However, the default Neuromore Studio layout doesn't have windows open for those outputs. To add a window for time-domain outputs, click on the View tab of the toolbar, then Add -> Signal View.

    A new window will appear. Click and drag the window to a convenient place in the Neuromore Studio Layout - it should snap into place, like below.

    If you look at the Classifier window, you will notice there are three "output" nodes (nodes with an eye symbol): Filtered Raw, Filtered FFT, and Viewer. The Filtered Raw and View symbols are time-domain, and are the two symbols in the Signal View.

    To add a window for frequency-domain outputs, click on View -> Add -> Spectrum View. Reposition the new window to a convenient place. You should see one signal, the Filtered FFT node.

    Want to double-check which signal corresponds to which output? Double click on one of the output nodes in the Classifier window. This should expand the Node Palette window. Display the Attributes tab and select "Custom Color". Double click on the block of color that appears to choose the color of your signal.

    In the example below, I selected the "Filtered Raw" node, and set the color to bright green. The corresponding signal is now bright green in the Signal View window.

    Now you're able to view the signals from your output nodes in your Classifier!

    This sort of graphical programming (or visual programming) also appears in very popular programs like PureData and MAX for more general purposes and OpenViBE and of course neuromore for EEG specific processing.

    The basic idea is that a stream of data that originates at the input device can then be mapped, processed and transformed into outputs that are useful, informative or just plain cool.

    The getting started example for OpenBCI in the neuromore Studio explores these areas and how to properly use the graphical programming interface.

    The best example within the classifier is perhaps the dynamic alpha detector.

    This alpha detector maintains a 30 sec average of the ratio between the alpha (8-12 Hz) and the background signal intensity. The detector itself reports an alpha reward that is dynamically changed by the average alpha/background ratio. This system is adaptive to lower or high alpha environments and makes alpha rewards harder when the average alpha ratio is high and vice-versa.

    By changing the "sensibility" parameter node you can then manually tune the relative "difficulty" that is necesary to attain an alpha detection.

    This system is flexible to different electrodes and electrode placement as it adjusts dynamically its expectations of what alpha "looks like".

    From this example we can see the power of statistics and simple logic that can easily be incorporated through visual programming into a complex and robust system.

    Documentation and Resources

    Did you use Neuromore and OpenBCI to build something new? Post about it on our forum!

    - - + + \ No newline at end of file diff --git a/Software/CompatibleThirdPartySoftware/OpenVibe/index.html b/Software/CompatibleThirdPartySoftware/OpenVibe/index.html index bba93f718..23092122d 100644 --- a/Software/CompatibleThirdPartySoftware/OpenVibe/index.html +++ b/Software/CompatibleThirdPartySoftware/OpenVibe/index.html @@ -12,15 +12,15 @@ OpenViBE | OpenBCI Documentation - - + +
    Skip to main content

    OpenViBE

    Overview

    There are two primary methods of connecting from OpenBCI tech to OpenViBE:

    1. You can connect the Cyton and Cyton+Daisy using an OpenViBE driver. This method is described below.

    2. Connect any OpenBCI Board to the OpenBCI GUI, then use the Networking Widget to stream data using LSL protocol to OpenViBE Acquisition Server. Start streaming from the GUI first. Select LSL in OpenViBE Acquisition Server. You should see an option in Driver Properties to select the data stream from the GUI, its typically auto-detected.

    Setting Up Your Environment

    Windows: Follow OpenBCI on Windows tutorial to properly connect your OBCI board on Windows. Then, continue this tutorial.

    OS X: Visit the Windows Virtual Box installation tutorial first, then follow these instructions. Note: you may have difficulty streaming live from your OpenBCI board to OpenViBE within a VM.

    Linux: Linux builds of OpenViBE also work. Some linux users might find this guide useful but keep in mind it is meant primarily for mac + win7.

    Installation

    Make sure you have a running Windows 7, 8.1, or 10 Machine (be it either a VM or native). Download the latest OpenViBE software from their website.

    Method 1: Connect Directly to Cyton or Cyton+Daisy using Dongle

    Getting Started

    Connect your OpenBCI board and make sure it is recognized as a COM port and its latency is set to 1 ms. To troubleshoot, read our OpenBCI on Windows tutorial.

    Start the OpenViBE Signal Acquisition Server (SAS). C: > Program Files > openvibe > openvibe-acquisition-server (normally shows up when searching โ€œopenvibeโ€ in start menu).

    COM Selection

    1. In the SAS select the OpenBCI (unstable means not throughly tested) option from the drop down list.
    2. Then open Driver Properties. In the Device option, select the COM port number your OBCI board was connected to.
    3. In the SAS Preference menu, change the drift tolerance from 2ms (default) to 10ms.
    4. Press Connect. If error, troubleshoot:
      • Look at the terminal window that the SAS opens up. It has a verbose report on the SAS's condition.
      • Often, pressing the restart button on the OBCI board, or Disconnecting/Connecting the Dongle will fix any connection issues.
      • If the error reports that it cannot open the selected port, make sure the COM port selected in the driver options is the same as your board.

    Configure OpenViBE Designer

    Click here to download the OpenBCI-OpenViBE example XML File. This file is a pre-made graph that will display both the EEG channels and the AUX channels. For the V3 board, the AUX channels correspond to accelerometer values in the three cardinal directions.

    Open the OpenViBE Designer GUI. If you are not using the example xml file, a blank page should open like below:

    image

    In the toolbar on the right, expand the "Acquisition and IO" folder and select "Acquisition client." This object represents the input stream from the OpenBCI board. Click and drag the Acquisition client into the design space.

    image

    From the same toolbar, expand the "Visualization" folder, then the "Basic" folder, and select "Signal display." Click and drag the Signal display box into the design space. Connect the similarly-colored triangles of the two boxes.

    image

    You're ready to stream data from your board! Return to the OpenViBE Acquisition Server GUI and select "Play."

    Return to the OpenViBE designer GUI. Click the play button from the top toolbar. A signal display window should pop up, displaying data as it streams from your OpenBCI board.

    image

    You're now streaming data from your OpenBCI board to OpenViBE! Feel free to explore the other tools OpenViBE has to offer.

    Method 2: Stream from the OpenBCI GUI to OpenViBE

    Please, refer to the following screenshot, YouTube video and/or steps below. For example, you can stream Ganglion+WiFi at 1600Hz from the OpenBCI GUI to OpenVibe, as seen in the screenshot. Here is a YouTube Video to document this method in detail.

    Click here to download the OpenBCI-OpenViBE example XML File. This file is a pre-made graph that will display both the EEG channels and the AUX channels. For the V3 board, the AUX channels correspond to accelerometer values in the three cardinal directions.

    We do not need the objects on the right to handle AUX channels. Sever the connection to the Aux data processing, since we will be sending just four channels TimeSeries data over LSL.

    As you can see in the YouTube Video, we need to make a few modifications to the OpenBCI-OpenViBE XML for this to work with Ganglion sent over LSL. Refer to the comments in the example.

    1. Open the OpenBCI GUI.
    2. Start a session with any data mode.
    3. Open the Networking Widget and set Protocol to LSL from the dropdown in the top right of the widget.
    4. Select desired data type to stream.
    5. IMPORTANT: In the OpenViBE Acquisition Server, select the Driver as LabStreamingLayer(LSL).
    6. Click Start in the OpenBCI GUI Networking Widget.
    7. Click Connect and Play in the OpenViBE Acquisition Server.
    8. Click the Play button in the OpenViBE Designer GUI.

    OpenBCI GUI to OpenViBE Screenshot

    Here is what the Acquisition Server Console Log should read when successfully connected: OpenBCI GUI to OpenViBE LSL Successful Connection

    Enjoy OpenBCI in OpenViBE!

    Documentation and Resources

    For more advanced tutorials using OpenBCI and OpenViBE, check out Jeremy Frey's blog. He has done both a P300 Speller and a Motor Imagery Classifier.

    For an example of a more advanced OpenViBE setup with OpenBCI, open the attached xml file in the OpenViBE designer GUI. This file is a pre-made graph that will display both the EEG channels and the AUX channels. For the V3 board, the AUX channels correspond to accelerometer values in the three cardinal directions.

    To learn more about OpenViBE, take a look at their documentation here.

    Build something new with OpenBCI and OpenViBE? Post about it on our community page!

    - - + + \ No newline at end of file diff --git a/Software/CompatibleThirdPartySoftware/VirtualBox/index.html b/Software/CompatibleThirdPartySoftware/VirtualBox/index.html index 958cd8bcc..4deedd311 100644 --- a/Software/CompatibleThirdPartySoftware/VirtualBox/index.html +++ b/Software/CompatibleThirdPartySoftware/VirtualBox/index.html @@ -12,13 +12,13 @@ VirtualBox Windows Guide | OpenBCI Documentation - - + +
    Skip to main content

    VirtualBox Windows Guide

    Some of the software compatible with OpenBCI products requires a Windows operating system. If you have a non-windows computer, you can still use this software through a Windows virtual machine on VirtualBox.

    Installing Windows 7 VM in VirtualBox

    1. Download VirtualBox.
    2. Go to https: and download a Windows 7 virtual machine (I used IE8) image for your appropriate host on the "Choose your OS" tab. (The OS that your computer runs natively). Choosing Virtual Box as the platform.
    3. Extract and double click on the .OVA file resulting from the extraction. This should start Virtual Box and set up your VM's configurations.
    4. Some EEG processing software uses a lot of RAM (OpenViBE aquisition server for example). In fact, some will take up one entire core, if they can. Because of this, I would advise that you configure your VM to have multiple cores and as much RAM as you deem reasonable.
    5. Import the VM, go through all the configs and start it.
    6. For more detailed instructions/tutorials and troubleshooting see the Windows Manual. (If you selected a different distribution other than Win 7, see the respective manual in the Windows page.)
    7. Follow the OpenBCI on Windows tutorial to properly connect your OBCI board on Windows.

    NOTE: Make sure that Guest Additions are installed correctly on your VM. With the image used, they should be automatically installed.

    Sharing files with VirtualBox

    If you have files on your regular OS that you'd like to access through VirtualBox, follow these steps to create a shared folder:

    1. Start VirtualBox. When the "Oracle VM VirtualBox Manager" window appears, select your virtual machine (so that it's highlighted in blue). Make sure your virtual machine is in the "powered off" mode, and not the "saved state" mode.
    2. Click Settings and then the "Shared Folders" tab.
    3. Click the icon for "Add new shared folder", and select the file path to a folder you'd like to share.
    4. Start your virtual machine.
    5. Open a file explorer window and navigate to the "Network" location.
    6. You may need to select "Turn on network and file sharing" as an administrator. Then, a computer called "VBOXSVR" will appear.
    7. Double click on that computer and you should see your shared folder.

    You're all set! For more information, look at the VirtualBox documentation.

    Using OpenBCI Hardware within VirtualBox

    While using 3rd party software, you might want to stream data from your OpenBCI board directly to a program on your virtual machine. Here's how to livestream from your OpenBCI board within your VM.

    OpenBCI Cyton Board

    1. Make sure you're comfortable using your Cyton board and Dongle with your host computer and the OpenBCI GUI. To do so, check out our Cyton Getting Started Guide.
    2. Plug in your Dongle and turn on your Cyton board. Both should display a blue light.
    3. Start VirtualBox. When the "Oracle VM VirtualBox Manager" window appears, select your virtual machine (so that it's highlighted in blue). Make sure your virtual machine is in the "powered off" mode, and not the "saved state" mode.
    4. Click Settings and then the Ports tab.
    5. Switch to the USB tab.
    6. Check "Enable USB Controller" and select "USB 2.0 (EHCL) Controller".
    7. Under USB Device Filters, click the "Add USB" icon with the green plus sign. The FTDI Driver used by the OpenBCI Dongle should appear in a drop down menu. Select it. It should now appear under "USB Device Filters".
    1. Click "OK" to save these settings. Make sure no other program that connects to your Dongle (like the OpenBCI GUI) is currently running. Start your virtual machine.
    2. From within your virtual machine, open the control panel, then navigate to Hardware and Sound -> Device Manager.
    3. You should see the FT USB driver under "Other devices". It may have a warning indicator next to it. Double-click the driver name.
    1. Doing so should open a "Properties" page. Go to the "General" tab and select "Update Driver..."
    1. Select "Search automatically for updated driver software" when prompted.
    2. Wait for your your VM OS to search for and download the driver software. You will be prompted when the driver software is downloaded successfully.
    3. Now, in the Device Manager, there should be an object under "Universal Serial Bus controllers" called "USB Serial Converter". There should also be a "Ports" tab with at least one device.
    1. The device listed under "Ports" is your OpenBCI Dongle, and the address in parenthesis is its COM Port. In the example above, the OpenBCI Dongle is on COM Port 3.

    You should now be able to communicate with your OpenBCI Dongle and board from within your VM! Have more questions? Post them on our Forum.

    - - + + \ No newline at end of file diff --git a/Software/OpenBCISoftware/GUIDocs/index.html b/Software/OpenBCISoftware/GUIDocs/index.html index f6efb3692..5b626c598 100644 --- a/Software/OpenBCISoftware/GUIDocs/index.html +++ b/Software/OpenBCISoftware/GUIDocs/index.html @@ -12,8 +12,8 @@ The OpenBCI GUI | OpenBCI Documentation - - + +
    @@ -31,7 +31,7 @@ On Windows C:\Users\Username\Documents\Processing\libraries
    On Linux /home/<user-name>/sketchbook/libraries

    If there is no folder called libraries in that location, go ahead and make one. Once you have done that, close the Processing app and reopen it. If you get an error saying "Duplicate Packages", you may need to remove the jna package from the Processing\libraries folder.

    Open The OpenBCI GUI Project in Processing & Launch It!

    note

    If you are on Windows, please set Processing to Run this program as an administrator.

    When you get Processing running again, you will see a window open up. This is the Processing IDE (Integrated Development Environment). Select File > Open and open the OpenBCI_GUI.pde file from where you saved your fork or clone of the repository.

    GUI Folder structure screenshot GUI code window

    If you don't know anything about coding, don't edit these files. If you like to dig in to the meat of what makes things work, by all means. have at it. You are looking at the program code that makes the OpenBCI GUI work it's magic. Now, it's time to run it!

    Processing RUN

    Press the play button on the upper left of the IDE, and the sketch will try to launch!

    If you are encountering issues launching the GUI at this point, please head to the OpenBCI_GUI section of our Forum and look for help or post a question.

    Converting Large SD Card Recordings

    Note: This can only be done with GUI v4.2.0 or earlier. In order to convert large SD card recordings made using Cyton or Cyton+Daisy, you will need to run the GUI from Processing, but we need to change one crucial setting in Processing's Preferences. As mentioned in the screenshot below, open Processing preferences and increase max available memory to at least 9GB to convert a 12 hour SD recording. Click OK to save these preferences, restart Processing to make sure the changes take effect, and re-launch the GUI.

    GUI Screenshot convert large SD recording

    Exported Data

    Data from the board will be recorded into a Brainflow-RAW_date_time CSV file and OpenBCI-RAW_date_time CSV file in txt format. All data saved to these files are unfiltered. These recordings are stored in User/Documents/OpenBCI_GUI/Recordings. Each GUI session will have its own directory titled OpenBCISession_date_time. Every time you start and stop the data stream, the GUI creates new recording files within that session folder. The picture below shows three recordings within one GUI session. The BrainFlow CSV files are generated by the BrainFlow Streamer feature when set to stream to file. This feature can also be used to send raw data over a network. By default, BrainFlow streamer saves data to this folder.

    GUI data files

    Cyton

    Here is a table of the column headers and descriptions for the Cyton.

    ColumnNameDescription
    1Sample IndexThe index of the sample per second (0-250)
    2EXG Channel 0EEG/EMG/ECG channel connected to N1P pins
    3EXG Channel 1EEG/EMG/ECG channel connected to N2P pins
    4EXG Channel 2EEG/EMG/ECG channel connected to N3P pins
    5EXG Channel 3EEG/EMG/ECG channel connected to N4P pins
    6EXG Channel 4EEG/EMG/ECG channel connected to N5P pins
    7EXG Channel 5EEG/EMG/ECG channel connected to N6P pins
    8EXG Channel 6EEG/EMG/ECG channel connected to N7P pins
    9EXG Channel 7EEG/EMG/ECG channel connected to N8P pins
    10Accel Channel 0Accelerometer channel 0 (X)
    11Accel Channel 1Accelerometer channel 1 (Y)
    12Accel Channel 2Accelerometer channel 2 (Z)
    13OtherSee below
    14OtherSee below
    15OtherSee below
    16OtherSee below
    17OtherSee below
    18OtherSee below
    19OtherSee below
    20Analog Channel 0Analog channel 0
    21Analog Channel 1Analog channel 1
    22Analog Channel 2Analog channel 2
    23TimestampUnix timestamp
    24Marker ChannelChannel for adding manual markers to data
    25Timestamp (Formatted)Year-Month-Day Hour:Minute:Second (Not in Brainflow csv)

    Here is a table of the column headers and descriptions for the Cyton + Daisy.

    ColumnNameDescription
    1Sample IndexThe index of the sample per second (0-250)
    2EXG Channel 0EEG/EMG/ECG channel connected to N1P pins on Cyton
    3EXG Channel 1EEG/EMG/ECG channel connected to N2P pins on Cyton
    4EXG Channel 2EEG/EMG/ECG channel connected to N3P pins on Cyton
    5EXG Channel 3EEG/EMG/ECG channel connected to N4P pins on Cyton
    6EXG Channel 4EEG/EMG/ECG channel connected to N5P pins on Cyton
    7EXG Channel 5EEG/EMG/ECG channel connected to N6P pins on Cyton
    8EXG Channel 6EEG/EMG/ECG channel connected to N7P pins on Cyton
    9EXG Channel 7EEG/EMG/ECG channel connected to N8P pins on Cyton
    2EXG Channel 8EEG/EMG/ECG channel connected to N1P pins on Daisy
    3EXG Channel 9EEG/EMG/ECG channel connected to N2P pins on Daisy
    4EXG Channel 10EEG/EMG/ECG channel connected to N3P pins on Daisy
    5EXG Channel 11EEG/EMG/ECG channel connected to N4P pins on Daisy
    6EXG Channel 12EEG/EMG/ECG channel connected to N5P pins on Daisy
    7EXG Channel 13EEG/EMG/ECG channel connected to N6P pins on Daisy
    8EXG Channel 14EEG/EMG/ECG channel connected to N7P pins on Daisy
    9EXG Channel 15EEG/EMG/ECG channel connected to N8P pins on Daisy
    10Accel Channel 0Accelerometer channel 0 (X)
    11Accel Channel 1Accelerometer channel 1 (Y)
    12Accel Channel 2Accelerometer channel 2 (Z)
    13OtherSee below
    14OtherSee below
    15OtherSee below
    16OtherSee below
    17OtherSee below
    18OtherSee below
    19OtherSee below
    20Analog Channel 0Analog channel 0
    21Analog Channel 1Analog channel 1
    22Analog Channel 2Analog channel 2
    23TimestampUnix timestamp
    24Marker ChannelChannel for adding manual markers to data
    25Timestamp (Formatted)Year-Month-Day Hour:Minute:Second (Not in Brainflow csv)
    Cyton Other Channels

    When recording using Cyton, the GUI will output a data file which contains 7 channels with the header "Other". These channels are user defined based on the board mode. Refer to the aux data footer section of the Cyton data format documentation for further information.

    In digital read mode, the 5th "Other" channel is connected to the D17 pin by default. This pin can be triggered by pressing the "PROG" button. This is useful for adding manual timestamps to your data.

    Ganglion

    Here is a table of the column headers and descriptions for the Ganglion.

    ColumnOpenBCI-RAWDescription
    1Sample IndexThe index of the sample per second (0-250)
    2EXG Channel 0EEG/EMG/ECG channel connected to N1P pins
    3EXG Channel 1EEG/EMG/ECG channel connected to N2P pins
    4EXG Channel 2EEG/EMG/ECG channel connected to N3P pins
    5EXG Channel 3EEG/EMG/ECG channel connected to N4P pins
    6Accel Channel 0Accelerometer channel 0 (X)
    7Accel Channel 1Accelerometer channel 1 (Y)
    8Accel Channel 2Accelerometer channel 2 (Z)
    9OtherNot used
    10OtherNot used
    11OtherNot used
    12OtherNot used
    13OtherNot used
    14TimestampUnix timestamp
    15Marker ChannelChannel for adding manual markers to data
    16Timestamp (Formatted)Year-Month-Day Hour:Minute:Second (Not in Brainflow csv)
    - - + + \ No newline at end of file diff --git a/Software/OpenBCISoftware/GUIWidgets/index.html b/Software/OpenBCISoftware/GUIWidgets/index.html index 5470093e5..08400f641 100644 --- a/Software/OpenBCISoftware/GUIWidgets/index.html +++ b/Software/OpenBCISoftware/GUIWidgets/index.html @@ -12,8 +12,8 @@ GUI Widget Guide | OpenBCI Documentation - - + +
    @@ -24,7 +24,7 @@ Some objects may need to be resized or re-positioned when the user changes the GUI screen size. This is why the widget class has the screenResized() method. Something not displaying right after the GUI is resized? This is where you need to add code. Typically, object x, y, width, and height are declared when the widget is instantiated, and again in screenResized() using relative positioning.

    Settings: To test that everything is working, you should see the data in a settings JSON file for each data mode in the Documents/OpenBCI_GUI/Settings/ folder. JSON files can be viewed as text. Confirm that your new JSON object and data are being written to file. Finally, confirm that the settings work properly when configuring the widget, saving, and loading.

    GUI Crash: One of the most common ways to crash the GUI with a new widget is drawing null data, or some other error related to draw(). Another common crash is an Exception, which will print to the console of Atom, VSCode, or Processing IDE.

    Step 7 - Share your custom widget with the world!

    If you make a functional widget that you think others could benefit from, please share it with the world by submitting a pull request to the OpenBCI_GUI repo!

    - - + + \ No newline at end of file diff --git a/Software/OpenBCISoftware/NeuroFly_Toolkit/index.html b/Software/OpenBCISoftware/NeuroFly_Toolkit/index.html index ea43d82b8..50805f015 100644 --- a/Software/OpenBCISoftware/NeuroFly_Toolkit/index.html +++ b/Software/OpenBCISoftware/NeuroFly_Toolkit/index.html @@ -12,13 +12,13 @@ NeuroFly Toolkit | OpenBCI Documentation - - + +
    Skip to main content

    NeuroFly Toolkit

    This tutorial will show you how to control a joystick using EMG data with the OpenBCI GUI. You can then use this customizable, muscle-activated joystick for any purpose of your choosing! OpenBCI used this to control a drone in the 2023 OpenBCI TED Talk.

    Materials Required

    1. OpenBCI Cyton Board or Ganglion Board
    2. Disposable gel electrodes or IDUN Dryode
    3. EMG/ECG Snap Electrode Cables
    4. Computer with downloaded OpenBCI GUI. Be sure to use OpenBCI GUI v5.2.0 or later.

    Video Walkthrough

    NeuroFly by OpenBCI - How it works

    Step 1: Hardware Assembly

    Follow the EMG Getting Started tutorial to connect the electrodes to your body and the Cyton board. We will read data from the Cyton using the OpenBCI GUI. For this tutorial, you will need to connect up to four channels. The number of channels depends on how many degrees of freedom are needed. Four channels will enable control of both positive and negative X/Y directions of the joystick. Only one ground is needed.

    Here is a mapping of channel numbers to X/Y joystick directions:

    ChannelDirection
    1- X (left)
    2+ X (right)
    3+ Y (up)
    4- Y (down)
    tip

    The most complex part of this tutorial will be finding the right placement for each pair of electrodes. It is important to find the muscle locations that are the easiest for the user to precisely control. You may need to play around with different locations before finding your optimal electrode setup.

    Step 2: GUI Setup

    Start by streaming data using the GUI. Follow this getting started tutorial to get the board streaming. You will need to open the EMG Joystick and EMG Settings widgets.

    EMG Settings

    This widget contains the tuneable parameters used for the threshold algorithm that determines how active each channel is. The output value is a normalized value, from 0 to 1, mapped between the lower threshold and upper threshold.

    EMG Settings Screenshot

    ParameterDefinition
    SmoothThis is the size of the window. If we set this value at the smallest setting of 0.01 seconds (ie., lowering the smooth value), our data will be very jittery but responsive. Alternatively, if we increase the smooth and set our window to 2.0 seconds, the output will be very smooth but much less responsive. This reduces the effect of outliers in the dataset.
    uV LimitThis is a cutoff point for an allowable ฮผV value in any individual data block. Any ฮผV values above this number will be chopped off and set to this upper ฮผV limit. This is to prevent erratic blips in the data from substantially distorting the average. Sometimes dropped packets and rapid body movements can create large spikes that donโ€™t correlate to muscle activity. This helps account for those issues.
    Creep+This value indicates how quickly the upper ฮผV threshold creeps downward. Notice that adjusting this value will affect how fast the the upper threshold decreases if not triggered. We generally recommend this to be slow. If this is too fast and we wait too long between muscle activations, the upper threshold will have crept too close to the lower threshold and the system will be hypersensitive.
    Creep-This value indicates how quickly the lower ฮผV threshold creeps upward. Notice that adjusting this value will affect how fast the lower threshold increases if it is less than the current uV. A higher value enables easier activation, but the signal is more prone to noise. A lower value is the opposite. It is harder to activate, but the signal will be less prone to noise.
    Min ฮ”uVThis value sets the minimum voltage range between the upper threshold and the lower threshold. The upper threshold and lower threshold cannot get any closer than this. Increasing this value will result in you having to create a larger EMG signal to go from 0 to 100% activation. This is useful when your EMG signal is strong, but can make it difficult to reach 100% if your EMG signal is weak. Decreasing the value will make it easier to reach 100% activation with a weak signal, but may result in false activations when the signal is strong.
    Low LimitThis is the minimum value the lower threshold can be. In general, this value should be set just above the noise floor so that environmental noise does not trigger false activations.
    tip

    It is important to note higher creep values adjust thresholds slower and lower creep values adjust faster. For example, if we compare creep = 0.9 and creep = 0.999 with a previous threshold value = 100:

    (0.9 x 100 = 90) < (0.999 x 100 = 99)

    You can see how a lower creep value will actually decrease the value faster.

    EMG Joystick Widget

    This widget has an indicator that moves in the direction of the activated EMG channels. This visualization should be used in combination with the EMG settings to find your ideal EMG joystick setup.

    EMG Joystick Screenshot

    Step 3: Stream Data Using Networking Widget

    Follow the Networking Tutorial to learn how to stream data using UDP from the GUI. For this project, you will need to stream the EMG channel data from the Networking Widget. Make sure your EMG joystick widget is open when streaming. Your Networking settings should look as follows:

    UDP Networking Widget Screenshot

    The EMG Joystick UDP stream will be sent to the IP address and port specified in the Networking Widget. The JSON packets will look like this:

    {"type":"emgJoystick","data":[0.664,-0.749]}

    Here is an example of how we use the deserialized JSON messages in our NeuroFly Unity application.

    EMGJoystickX = packet.data[0];
    EMGJoystickY = packet.data[1];

    Once your UDP stream is running, you will be able to use this EMG joystick for any use case! We are excited to see how our global Community uses this widget to create awesome projects and research!

    - - + + \ No newline at end of file diff --git a/Software/SoftwareLanding/index.html b/Software/SoftwareLanding/index.html index a4c4d2197..7d6163112 100644 --- a/Software/SoftwareLanding/index.html +++ b/Software/SoftwareLanding/index.html @@ -12,13 +12,13 @@ Compatible Software | OpenBCI Documentation - - + +
    Skip to main content

    Compatible Software

    OpenBCI Software

    This section details the various OpenBCI-specific software and SDKs. Included here are guides on how to use the OpenBCI GUI, as well as information about developing for OpenBCI with common languages like Python, Java, Node.js, and more!

    Compatible Third-Party Software

    This section details a number of third-party programs that can be used in conjunction with OpenBCI software.

    Sample Live Data

    Video of the OpenBCI GUI posted on Youtube, showing the 8-channel Cyton Board paired with a 5-channel EEG Headband Kit.

    - - + + \ No newline at end of file diff --git a/ThirdParty/EmotiBit/EmotiBit_Guide/index.html b/ThirdParty/EmotiBit/EmotiBit_Guide/index.html index 02ee047f0..f83b5dc61 100644 --- a/ThirdParty/EmotiBit/EmotiBit_Guide/index.html +++ b/ThirdParty/EmotiBit/EmotiBit_Guide/index.html @@ -12,8 +12,8 @@ EmotiBit Guide | OpenBCI Documentation - - + +
    @@ -21,7 +21,7 @@ You can select from different EmotiBit options to get the one thatโ€™s right for you. Fully open-source, cross-platform data visualizer software (Windows, Mac, Linux) is included with all options.

    Want to take the guesswork out of ordering? Check out the All-in-one Emotibit Bundle that includes everything you need to get started measuring research-grade biometric signals, and get $25 off!

    What is the difference between the EmotiBit Emo and MD Boards?

    Product nameWhat's IncludedPrice
    EmotiBit Emo
    • PPG Sensor (3-wavelength)
    • EDA / GSR sensor (+AgCl snap electrodes)
    • 9-axis IMU (Accel, Gyro, Mag)
    • Temperature sensor (standard-grade)
    • Numerous derivative biometric streams
    • Finger strap
    $249.99
    EmotiBit MD
    • Everything on EmotiBit Emo
    • PLUS a medical-grade temperature sensor (thermopile) for sensing even more accurate body temperature
    $349.99

    ###Do I need a kit? You need several items in the Essentials Kit to use EmotiBit, including:

    We highly recommend you get an Essentials Kit to use EmotiBit out of the box, but weโ€™re offering EmotiBit board-only options without a kit in case you already have all these parts or if you want to adapt the EmotiBit firmware to use another Feather or configuration.

    We also have an Electrode Kit for folks who want spares and additional flexibility to use EmotiBit in research and other high-use settings.

    Product nameWhat's IncludedPrice
    Essentials Kit
    • Adafruit Feather M0 WiFi
    • 400mAh battery (up to 10 hours use in data-logger mode)
    • High-speed microSD card
    • MicroSD card reader
    • Micro USB cable
    • 3 Emoti-stretch straps of different lengths to wear EmotiBit nearly anywhere on the body, ranging from a childโ€™s wrist to an adult head
    $114.99
    Electrode Kit
    • 10x EDA electrodes (Ag/AgCl)
    • 5x solder-cup snaps (to add your own EDA leads)
    • 5x Emoti-genic covers (provides an additional hygienic layer and sweat protection)
    $34.99

    How to use it

    EmotiBit_setup

    1. Stack

    Stack EmotiBit with any Adafruit Feather module, insert an SD card, and plug in a battery.

    2. Sense

    Place EmotiBit almost anywhere on the body and launch the visualizer to start viewing physiological data.

    3.Stream

    Save data to an SD card, stream via LSL, OSC, TCP, etc, or open up the code and do anything you want!

    Who makes EmotiBit?

    Learn more about EmotiBit and the team behind it on the EmotiBit website.

    Head to the EmotiBit Github for complete guides and documentation. Happy sensing!

    EmotiBot

    - - + + \ No newline at end of file diff --git a/ThirdParty/IDUN_Dryode/Dryode/index.html b/ThirdParty/IDUN_Dryode/Dryode/index.html index 9990cf094..d35392cb4 100644 --- a/ThirdParty/IDUN_Dryode/Dryode/index.html +++ b/ThirdParty/IDUN_Dryode/Dryode/index.html @@ -12,13 +12,13 @@ IDUN Dryode | OpenBCI Documentation - - + +
    Skip to main content

    IDUN Dryode

    Overview

    We are very excited to work with IDUN Technologies to offer this affordable, high-quality biosensing kit to our community!

    The Dryodeโ„ข offers waterproof, research-grade signal quality with the ease of a consumer product. This state-of-the-art flexible dry electrode is designed for biopotential data acquisition (ECG, EMG, and EEG). It is connectable to the OpenBCI Cyton, CytonDaisy, or Ganglion board using OpenBCI snap electrode cables, as well as compatible with most standard snap electrode cables.

    Head over to the EMG Getting Started Guide to learn how to connect the EMG set-up!

    - - + + \ No newline at end of file diff --git a/ThirdParty/Myoware/MyoWareCyton/index.html b/ThirdParty/Myoware/MyoWareCyton/index.html index 473322c59..de515539b 100644 --- a/ThirdParty/Myoware/MyoWareCyton/index.html +++ b/ThirdParty/Myoware/MyoWareCyton/index.html @@ -12,13 +12,13 @@ MyoWare OpenBCI Integration (Cyton Board) | OpenBCI Documentation - - + +
    Skip to main content

    MyoWare OpenBCI Integration (Cyton Board)

    caution

    The Myoware 2.0 board cannot be used with the Ganglion board. If you have purchased a Myoware 2.0 board with the intention of using it with the Ganglion board, please contact Customer support at contact@openbci.com

    Overview

    This tutorial will show you how to read EMG data (electrical signals from muscles) using a MyoWare board, an OpenBCI Cyton board, and the OpenBCI GUI.

    MyoWare Pin Side | MyoWare Snap Side

    Materials Needed

    1. MyoWare board
    2. OpenBCI Cyton board, with power source
    3. OpenBCI dongle
    4. Disposable 24mm sticky electrodes (for using the MyoWare board)
    5. Soldering iron and materials
    6. Five male header pins (like these)
    7. Five male-female jumper wires (like these)

    Note: Jumper wires and header pins aren't sold on the OpenBCI website, but we used some from Adafruit (linked above) for this tutorial

    1. Soldering the MyoWare Headers

    Break the male headers into a set of 2-pin headers and 3-pin headers as shown below

    Header pins for MyoWare

    Solder the 3-pin header to the VIN, GND and ENV pads and solder the 2-pin header to the RECT and RAW pads of the MyoWare board.

    MyoWare Board post-soldering

    The male-female jumper wires can then be used to interface with the Cyton from the MyoWare board. The female part of the jumper wire is plugged into the MyoWare whereas the male part is plugged into the Cyton.

    2. Preparing OpenBCI Cyton Board

    Your Cyton board should look like this:

    Board with Headers

    If your Cyton board is missing the black, female pin connectors (called "headers") sticking out of the board, you will need to solder them on before continuing.

    3. Wiring the MyoWare Board to the OpenBCI Cyton Board

    Connect the 5 wires from the MyoWare board in step 1 to the OpenBCI board, as shown below:

    Board with MyoWare

    The wires attached to the "VIN" and "GND" pins will be used to supply power to the board. They'll be attached to the DVDD and GND headers on the OpenBCI Cyton board respectively.

    The ENV, RECT and RAW headers are the output pins of the MyoWare Sensor. The ENV pin provides Envelope output, RECT provides Rectified output and RAW provides Raw EMG data from the MyoWare Sensor.

    The ENV, RECT and RAW pins should be connected to the Analog input pins of the Cyton, namely D12 and D13. For this tutorial, we have used D12 to demonstrate EMG Output. D11 cannot be used as an Analog pin. It can only receive Digital Input.

    The wires should be connected like this:

    MyoWare BoardOpenBCI Board
    VINDVDD
    GNDGND
    RAW/RECT/ENVD12

    When you have everything wired up, turn on the Cyton board, connect the USB dongle to your computer, and start the OpenBCI GUI software. If you're new to using an OpenBCI board with your computer, take a look at the Cyton Getting Started Guide.

    4. Streaming EMG Data with the OpenBCI GUI

    Attach three sticky electrodes to the three electrodes on the MyoWare board, and then stick the board on a muscle you'd like to monitor. The Sparkfun Hookup Guide for MyoWare has good guidelines for MyoWare board placement.

    You'll be able to see signals from the MyoWare board in the OpenBCI GUI using the Analog Read widget. The Analog Read widget is used to read signals from the Analog pins of the Cyton.

    Here's what the GUI, and pin D12, will look like with the muscle at rest:

    Resting

    Here's what D12 will look like after flexing the muscle:

    Firing

    - - + + \ No newline at end of file diff --git a/ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing/index.html b/ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing/index.html index 91f0bf9bf..a783cbbd2 100644 --- a/ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing/index.html +++ b/ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing/index.html @@ -12,8 +12,8 @@ Pulse Sensor Guide | OpenBCI Documentation - - + +
    @@ -23,7 +23,7 @@ Red pulse sensor cable goes to DVDD header on the Cyton, black to GND (right next to DVDD), and purple to D11. This D11 is read as analog pin A5, and sent in the first Aux data slot. The pulse sensor data will be pre-processed in the pulse sensor widget. When you download the OpenBCI GUI, the pulse sensor widget is pre-packaged in it.

    The connections are circled above.

    Pulse Sensor Wire ColorCyton Board HeaderFunction
    redDVDDpower
    blackGNDground
    purpleD11Analog input (signal)

    Red pulse sensor cable goes to DVDD header on the Cyton, black to GND (right next to DVDD), and purple to D11.

    After you have set up your hardware and software using the above steps, Please scroll through the general guide to learn how to secure the pulse sensor to your finger.

    When running the GUI, select the pulse sensor widget option from the dropdown menu, then hit 'Analog Read On, then go to another pane of the GUI and select 'Analog Read' from the dropdown menu. The pulse sensor widget will display your pulse data, and the Analog Read widget displays data from analog input A5, A6, and A7. Since you connected the purple wire of the pulse sensor to the D11 header, the data will show up in the A5 channel of the Analog Read Widget.

    Troubleshooting

    Running into trouble? Consult the OpenBCI Tech support Forum.

    For cyton-pulse sensor posts: here.

    You can find all relevant posts by using our site-specific Google Search Function.

    - - + + \ No newline at end of file diff --git a/ThirdParty/ThinkPulse/ThinkPulse/index.html b/ThirdParty/ThinkPulse/ThinkPulse/index.html index 4c54ae5d6..60f518ef3 100644 --- a/ThirdParty/ThinkPulse/ThinkPulse/index.html +++ b/ThirdParty/ThinkPulse/ThinkPulse/index.html @@ -12,15 +12,15 @@ ThinkPulse Getting Started Guide | OpenBCI Documentation - - + +
    Skip to main content

    ThinkPulse Getting Started Guide

    Available exclusively worldwide only on the OpenBCIยฎ store.

    About Conscious Labs

    Conscious Labs has been working since 2014 on taking neuroscience out of the lab and into the wild. They bring the technology, the team and the expertise to integrate EEG sensors into head wearables and hearables.

    We are very excited to partner with Conscious Labs to offer this affordable, high-quality biosensing kit to our community. The ThinkPulseโ„ข kit offers research-grade dry, active electrode EEG sensors at an unprecedented price point and comfort level.

    ThinkPulseโ„ข is a product of Conscious Labs (France). Patents issued and pending. Made in France.

    The ThinkPulseโ„ข system is an add-on to the Ultracortex EEG Headset plus Cyton Board This kit has been designed and its compatibility tested for the 8 and 16 channel Ultracortex with OpenBCI Cyton/CytonDaisy boards. For more compatibility and customization options as well as general product questions, please contact us support@openbci.com..



    ThinkPulse Starter Kit $349.99 Contents


    ThinkPulse contents


    Note, the replacement set $99.99 is just for those who want backup electrode tips. The Starter Kit $349.99 includes the necessary electrodes and electrode tips.



    How to Use the ThinkPulse Starter Kit with the Ultracortex Headset

    Below is the step-by-step tutorial by Conscious Labs on how to install the ThinkPulse Starter Kit on the Ultracortex. If you are doing this for the first time, allow yourself 20 minutes to put it together. You may briefly need a soldering iron and soldering wire at Step 3. If you do not have a soldering iron, you can still assemble the ThinkPulse! Keep reading for the solder-free option.

    Step 1: Prep Your Ultracortex Mark IV EEG Headset

    Ultracortex prep

    Step 2: Install the ThinkPulseโ„ข sensors on the Ultracortex

    install sensors

    Step 3: Assemble the ThinkPulseโ„ข Power Supply Board

    assemble power supply

    The assembly video shows how to install the power supply board to a post-2018 Cyton and a pre-2018 Cyton.

    Some early ThinkPulse units have a hardware bug. The fix is a straightforward, quick solder job. The first minute of the video explains how to do it.

    ThinkPulse kits that shipped post-January 2021 are fixed and do not require soldering. If you need help or have any questions, email support@openbci.com

    Step 4: Connect and organize the cables

    cable management



    Step 5 (For 16-channel kit) Connect and organize the cables

    cable management

    Using the ThinkPulseโ„ข sensors with OpenBCI Cyton Board

    The following information applies specifically to Cyton and Cyton+Daisy Boards. If you are seeing RAILED in the GUI, try the following tips:

    1. Disconnect the BIAS earclip from the Cyton board.
    2. Go to the Hardware Settings (button is found above Time Series widget) and turn BIAS and SRB1 to NO and OFF.
    3. Keep SRB2 ON.
    4. For every channel, set the GAIN to '8' or less.
    5. Below, you will find a screenshot of what this should look like in the GUI Hardware Settings. If you are communicating directly with the Cyton, the command correlating to this picture would be x1040010X.
    6. Pressing the Save button at the bottom of the Hardware Settings will allow you to store this configuration as a file.
    7. Next time you want to use the Cyton with ThinkPulse Electrodes, open Hardware Settings to Load and then Send channel settings. If you are using BrainFlow outside of the GUI, simply send these commands after instantiating the Board.

    ThinkPulse and Cyton Channel Setting Example

    Technical Specs and Data Sheet

    Full Technical Information


    ParametersSpecs
    Electrode Height7 mm
    External Diameter19 mm
    Bio-contact Area Diameter15 mm
    MaterialConductive polymer
    Polymer Dielectric Resistivity3.6 Ohm.cm
    Through Polymer Resistance<70 Ohm
    Typical Consumption5 mW
    Active amplification Gain0 dB
    Electrode Noise<10nV
    Bandwidth>10KHz

    Additional Troubleshooting

    When using the ThinkPulse Active Electrodes with Cyton, make sure to set the correct channel settings. This should resolve most issues. If you still have issues, you can reach out on the OpenBCI Forum or send us an email at contact@openbci.com.

    You can also refer to this resolved troubleshooting thread in the OpenBCI Technical Forum.

    Non-medical Use Disclaimer

    The ThinkPulseโ„ข Starter Kit and the ThinkPulseโ„ข Electrode Set are not medical devices and are not intended for medical diagnosis. These products are provided to you "as is." OpenBCI, Inc. provides the above product under the following conditions: This evaluation kit is intended for use for ENGINEERING DEVELOPMENT, DEMONSTRATION, OR EVALUATION PURPOSES ONLY.

    - - + + \ No newline at end of file diff --git a/ThirdParty/ThirdPartyLanding/index.html b/ThirdParty/ThirdPartyLanding/index.html index ea13335cd..9fe772cbc 100644 --- a/ThirdParty/ThirdPartyLanding/index.html +++ b/ThirdParty/ThirdPartyLanding/index.html @@ -12,15 +12,15 @@ Third-Party Hardware | OpenBCI Documentation - - + +
    Skip to main content

    Third-Party Hardware

    The directory to the left contains documents to explain the integration between OpenBCI and compatible third-party hardware. This landing page summarizes the variety of sampling modalities!

    EmotiBit

    EmotiBit

    Designed by our good friend Sean Montgomery and his team, EmotiBit can stream 16+ signals from the body (EDA, 3-wavelength PPG, high-res body temperature, humidity and a 9-axis IMU). We think it's the perfect complement to add emotional, physiological and movement data to your EEG recordings!

    EmotiBit is a wearable sensor module for capturing high-quality emotional, physiological, and movement data. Easy-to-use and scientifically-validated sensing lets you enjoy wireless data streaming to any platform or direct data recording to the built-in SD card. Customize the Arduino-compatible hardware and fully open-source software to meet any project needs!

    Tutorial Coming Soon!

    HEGduino

    The "HEG" in HEGduino stands for HemoEncephaloGraphy, a non-invasive biofeedback method. HEG detects regional changes in the brainโ€™s energy consumption via changes in blood-oxygen. HEGduino enables you to see in real time how your brain blood-oxygen levels respond to your thoughts and actions, resulting in a simple and elegant biofeedback system. You can easily affect and eventually control regional blood flow in your head by focusing, breathing, and relaxing, and watching the response on your screen. With the biofeedback provided by HEGduino, you can exercise your brain and make it healthier with mindful practice.

    We're partnering with HEGduino to bring you low-cost at-home HEG technology. Brain blood-flow biofeedback meets open-source IoT technology! These kits are hand-assembled and tested by their team to run out-of-the box. No firmware tinkering or wire soldering needed!

    The open-source, extensively documented HEGduino Kit is now available at the OpenBCI Shop.

    IDUN Dryode

    Introducing research-validated dry electrodes for sampling frontal cortex EEG and facial/body EMG, compatible with OpenBCI boards and standard snap cables!

    MyoWare

    myoware

    The MyoWare muscle sensor can be integrated with both the OpenBCI Cyton and Ganglion. To find out how, check out these tutorials:

    Pulse Sensor

    pulse sensor

    The Pulse Sensor is one of the third-party add-ons offered in our store.

    It can be connected to the Ganglion, Cyton, or any Arduino board to easily obtain your heart rate using photoplethysmogram (PPG).

    ThinkPulse Active Electrodes

    We are very excited to partner with Conscious Labs to offer this affordable, high-quality biosensing kit to our community. The ThinkPulseโ„ข kit offers research-grade dry, active electrode EEG sensors at an unprecedented price point and comfort level.

    Wifi Shield

    wifi shield The Wifi Shield is an add-on module that allows you to connect an OpenBCI Board to the GUI and send data over Wifi rather than Radio/BLE. To learn more about it, see these documents:

    - - + + \ No newline at end of file diff --git a/ThirdParty/WiFiShield/WiFiAPI/index.html b/ThirdParty/WiFiShield/WiFiAPI/index.html index fd877b57b..b9df830a5 100644 --- a/ThirdParty/WiFiShield/WiFiAPI/index.html +++ b/ThirdParty/WiFiShield/WiFiAPI/index.html @@ -12,14 +12,14 @@ OpenBCI WiFi Shield API | OpenBCI Documentation - - + +
    Skip to main content

    OpenBCI WiFi Shield API

    The OpenBCI Wifi Shield seeks to offer a plug and play Wifi solution for the OpenBCI Cyton and Ganglion.

    Overview

    One of the coolest parts of the WiFi Shield is its HTTP web server. For developers looking to get data from OpenBCI with a WiFi Shield, these HTTP commands will allow you to stream data to your applications over TCP or MQTT.

    Prerequisites

    Follow the WiFi Getting Started Guide to get your WiFi Shield on your Wireless Network.

    Get Wifi Shield on Local Wireless Network

    Be sure that your WiFi Shield is on your local network.

    The steps for connecting to the Wifi Shield and streaming over TCP:

    1. Get IP Address of the Wifi Shield
    2. Open a TCP Socket on Host Computer
    3. Send POST /tcp http request with open socket IP/Port number, can include options (i.e. output format of JSON or RAW output, use delimiters between packets, adjust latency)
    4. Send GET /stream/start or GET /stream/stop

    The steps for connecting to the Wifi Shield and streaming over MQTT:

    1. Find IP Address of Wifi Shield
    2. Set up MQTT broker
    3. Send POST /mqtt http request with broker address with optional username and password
    4. Send GET /stream/start or GET /stream/stop

    Get IP Address of Wifi Shield

    To programmatically discover WiFi Shields on your local network use Simple Service Discovery Protocol (SSDP) to find the device on your local network.

    Node.js OpenBCI WiFi Driver will implement SSDP for you.

    Use the OpenBCI WiFi GUI which will use the OpenBCI Electron Hub to find WiFi Shields IP Address. THE OPENBCI_HUB HAS BEEN DEPRECATED, TO ACCESS THIS FEATURE USE GUI V4.2.0. You can also get the IP address in GUI v5 by selecting the WiFi shield from the list. Depending on your network configuration, it may not show automatically.

    Use a graphical user interface Mac - Lan Scan

    We are still hashing out the best ways to discover the Wifi shield on the networks (home vs. enterprise and beyond) so please contribute ides if you have any on this github issue and we can add it in! Wifi Direct Feature Request (researcher frequently requested feature)

    Open a TCP Socket on Host Computer

    In order to get low latency high-reliability wireless data transmission we will open a TCP socket on your host Computer. The Wifi Shield will stream data to this socket.

    Raw Output Mode

    In raw output mode the data format follows the OpenBCI 33byte Binary Data Format. Even the Ganglion over WiFi Shield will send in the 33byte with the first four channels containing data and the upper four channels are all zeros.

    JSON Output Mode

    In json output mode, the WiFi Shield will convert raw data into nano volts. As of v3.0.0 firmware for Cyton and v2.0.0 firmware for Ganglion, the gain for each channel will be sent to the WiFi Shield once at the first connection between devices, and once each time the Ganglion or Cyton receives a start of streaming command. The WiFi Shield will connect to an NTP server to get the time once, and the WiFi Shield will then send the data in JSON.

    The JSON Adheres to the popular LSL stream format by default


    {
    "chunk": [
    {"data": [<float>, ..., <float>], "timestamp": <float> },
    ...
    {"data": [<float>, ..., <float>], "timestamp": <float> }
    ]
    }

    Examples

    Buffer of 5 samples. Each sample has 4 channels:


    [
    { "data":[ 7056745022195285, -475495395375, 475495395375, -495395375], "timestamp": 1497479774194733},
    { "data":[ 7056745022195285, -475495395375, 475495395375, -495395375], "timestamp": 1497479774195230},
    { "data":[ 7056745022195285, -475495395375, 475495395375, -495395375], "timestamp": 1497479774195735},
    { "data":[ 7056745022195285, -475495395375, 475495395375, -495395375], "timestamp": 1497479774196209},
    { "data":[ 7056745022195285, -475495395375, 475495395375, -495395375], "timestamp": 1497479774196715}
    ]

    OpenBCI WiFi Shield HTTP Rest Server

    Send /tcp http request for TCP configuration

    Refer to http server description swagger.io page as the single source of truth in regards to the OpenBCI Wifi Server. There are many options such as output mode for JSON or raw output, latency, delimiters and many more awesome options to help you easily process data in a driver.

    Send /mqtt http request for MQTT configuration

    Refer to http server description swagger.io page as the single source of truth in regards to the OpenBCI Wifi Server. There are many options such as output mode for JSON or raw output, latency, delimiters and many more awesome options to help you easily process data in a driver.

    Send /command http requests for control

    Refer to http server description swagger.io page as the single source of truth in regards to the OpenBCI Wifi Server. To change the sample rate of the Cyton, please use the ~ command as defined in the Cyton SDK docs.

    Send /latency http requests for tuning

    Refer to http server description swagger.io page as the single source of truth in regards to the OpenBCI Wifi Server.

    The time in micro seconds (us) between packet sends. The higher the OpenBCI sample rate, the higher the latency needed. Default is 1000us, minimum stable is 50us. For upper limit sample rates such as 4kHz/8kHz/16kHz, latency around 20ms seems to really stabilize the system.

    Parsing Data from Wifi Shield

    Data can be sent from the Wifi shield in two different formats: raw and JSON.

    raw Byte Stream Format

    The first byte to send is the control byte. For streaming data, that goes on the TCP socket, send 0xCX (where X is 0-F in hex) as the control byte. In the OpenBCI_32bit_Library code base:


    /*
    * @description Writes channel data and axisData array to serial port in
    * the correct stream packet format.
    */
    void OpenBCI_32bit_Library::sendChannelDataWifi(void) {

    wifiStoreByte(OPENBCI_EOP_STND_ACCEL); // 0xC0 1 byte

    wifiStoreByte(sampleCounter); // 1 byte

    ADS_writeChannelDataWifi(); // 24 bytes

    accelWriteAxisDataWifi(); // 6 bytes

    wifiFlushBuffer(); // Flushes the buffer to the SPISlave ESP8266 device!

    sampleCounter++;

    }

    This code writes 32 bytes of data in the correct format and therefore as soon as it arrives at the Wifi shield. The Wifi shield will convert the 32 byte packet to the standard 33 byte binary format by moving the control byte 0xCn, where n is 0-F (hex), to the stop position and add add 0xA0 to the start position. This allows for a seamless integration with the tried and tested parsing systems already built for the Cyton. Important if you want to only send 20 bytes of data per packet, you still must send this 32 bytes with the proper start and stop bytes.

    JSON format

    Suggested options for POST /tcp or POST /mqtt


    {
    "port": ..., // Enter your local server port
    "ip": ..., // Enter your local ip address of server
    "delimiter": true, // will place `\r\n` at end of each chunk
    "latency": 20000, // Time to wait between packet sends in micro seconds.. i.e. latency here is 20ms
    "sample_numbers": false, // Don't include sampleNumber in each sample
    "timestamps": true // Include timestamps in each sample
    }

    Now when you start streaming data, you can simply look for `\r\n` in the incoming stream of data and each time you find it, you know you just got then end of packet and can parse everything before that `\r\n` as JSON.


    - - + + \ No newline at end of file diff --git a/ThirdParty/WiFiShield/WiFiLanding/index.html b/ThirdParty/WiFiShield/WiFiLanding/index.html index d2edd98a1..3236c5073 100644 --- a/ThirdParty/WiFiShield/WiFiLanding/index.html +++ b/ThirdParty/WiFiShield/WiFiLanding/index.html @@ -12,8 +12,8 @@ OpenBCI WiFi | OpenBCI Documentation - - + +
    @@ -21,7 +21,7 @@ Wifi Top Layer
    Bottom Layer
    Wifi Bottom Layer

    Buttons

    The top push button, RESET, is a reset button that will power cycle the ESP8266 chip. Don't press the RESET button when a Ganglion is attached, if you want to power cycle the WiFi Shield, send a ; command to the Ganglion or Cyton to trigger a power on reset of the WiFi Shield. The bottom button, PROG, is use for programming the WiFi Shield over serial UART and is hooked up to GPIO 0.

    GPIO Pins Used by WiFi Shield

    The WiFi Shield breaks out every GPIO on the Cyton and Ganglion, however, two of the GIPO pins have been used to make the WiFi Shield work, one pin is used for reset and the other is for a chip select line used in SPI communications.

    Cyton

    The WiFi Shield uses D13 and D18, leaving three other pins, D11, D12, and D17. In analog mode this means you can't read A7 when WiFi Shield is attached.

    Ganglion

    The WiFi Shield uses D_24 and D_4 (A_5). Leaving all other pints open for use!

    - - + + \ No newline at end of file diff --git a/ThirdParty/WiFiShield/WiFiProgam/index.html b/ThirdParty/WiFiShield/WiFiProgam/index.html index 68981ce21..500012310 100644 --- a/ThirdParty/WiFiShield/WiFiProgam/index.html +++ b/ThirdParty/WiFiShield/WiFiProgam/index.html @@ -12,8 +12,8 @@ Wifi Shield Programming Tutorial | OpenBCI Documentation - - + +
    @@ -26,7 +26,7 @@ FTDI Friend Back

    Another example would be the FTDI Friend from Adafruit. I cut the trace on the RTS and 5V pads as well. These are the correct settings for uploading to ESP8266 using FTDI Friend. These breakouts are awesome and how the board was developed.

    FTDI Basic Breakout

    FTDI BasicFront FTDI BasicBack

    Sparkfun makes an FTDI breakout as well, and they come in a couple of flavors. 5V and 3V. By now, you know that you want the 3V Version. [pic coming soon] Also, if you have a version of this board with a voltage selection on the back, make sure that it has the 3.3V pads connected and the 5V pads cut!

    OpenBCI Cyton Dongle

    The OpenBCI Dongle can be used to upload firmware to ESP8266. See the section on how to pass through the code in the Cyton Radio Programming Guide.

    Download Compiled Binary for Upload

    Install Python Dependency

    You will need either Python 2.7 or Python 3.4 or newer installed on your system.

    Download and Install esptool

    The latest stable esptool.py release can be installed from pypi via pip:


    $ pip install esptool

    With some Python installations this may not work and you'll receive an error, try python -m pip install esptool or pip2 install esptool.

    After installing, you will have esptool.py installed into the default Python executables directory and you should be able to run it with the command esptool.py.

    In Windows, we use Command Prompt.

    Download the WiFi Shield Firmware

    First, download the file called DefaultWifiShield.bin from the latest release OpenBCI_WiFi Github repository.

    Save to your downloads folder. download the latest binary

    Get the Serial Port of Programmer

    The correct serial port for your OpenBCI Dongle or FTDI friend will be


    * On Macs, this will be named **/dev/tty.usbserial-DN00nnnn** where the nnnn is a combination of numbers and letters specific to your programmer of choice.

    * On Windows, the serial port will be listed as a numbered COM port.

    * On Linux, it will be different.

    Connect WiFi Shield to Programmer

    Hook up the FTDI friend, OpenBCI Dongle, or other UART-USB programmer to the Wifi Shield. Don't power the Wifi shield through the FTDI friend.

    FTDI_FriendWifi Shield
    GNDGND
    RXTX
    TXRX

    Wifi to FTDI friend

    Isolate and Power WiFi Shield

    Next, remove your wifi shield from the Cyton or Ganglion if it's not already.

    Remove your Wifi Shield from the Cyton/Ganglion board. Always use a spudger to remove your WiFi Shield from a Cyton or Ganglion.

    Wifi alone

    Plug a battery into the WiFi Shield and power the Shield by turning the power switch to the ON position.

    Plug in battery to the WiFi Shield.

    Battery to wifi shield

    Next, power the Wifi shield.

    Battery to wifi shield

    Put WiFi Shield in Bootloader Mode

    Press and hold the PROG button.

    Wifi programming hold prog

    Press and release the RESET button while holding PROG.

    Wifi programming hold reset

    Wifi programming release reset

    Finally, release the PROG button.

    Wifi programming release reset

    You should see no lights on the WiFi Shield if it is in bootloading mode.

    Upload Code

    On Mac/Linux

    From terminal you installed esptool.py to earlier, substitute your serial port name for YOURPORT in the command below.


    $ esptool.py --port /dev/tty.usbserial-YOURPORT write_flash 0x000000 ~/Downloads/DefaultWifiShield.bin

    On Windows

    From Command Prompt you installed esptool.py to earlier, substitute your serial port name for COM4 in the command below.


    $ esptool.py --port COM4 write_flash 0x000000 Downloads\DefaultWifiShield.bin

    Compile Source Code to build binary

    Prerequisites to Compile Source Code

    You will need:

    You will need:

    Download Latest Arduino

    Install Firmware From Arduino Library Manager (easiest!)

    Don't know what the Library Manager is? Skim over the Official Arduino Guide.

    Open the Library Manager and then

    1. Search for OpenBCI and install the latest version for OpenBCI_Wifi.

    2. Search for WiFiManager and install the latest version for WiFiManager.

    3. Search for ArduinoJson and install the latest version for ArduinoJson.

    4. Search for PubSubClient and install the latest version for PubSubClient.

    5. Search for Time and install the latest version for Time v1.5.0 by Michael Margolis, you will need to scroll down to the T section.

    6. Search for ntp and install the latest version for NtpClientLib (NOT NtpClient).

    7. Use the Library Manager to search for and install:

    Manual Installation of Ganglion Firmware (harder)

    1. Download the latest zips for the following libraries:

    2. Unzip the folders and change the names to:

    - OpenBCI_Wifi
    - WiFiManager
    - ArduinoJson
    - PubSubClient
    - Time
    - NtpClientLib
    1. Move all folders to:
    On Mac: /Documents/Arduino/libraries
    On Windows: C:\Users\username\Documents\Arduino\libraries

    If you don't have a libraries folder there, go ahead and make one.

    If you're have trouble or want to learn more checkout the Official Arduino Guide for manual installation.

    Clone The Repo From Github

    Developers looking to contribute or write custom firmware can clone the firmware repositories directly to your libraries folder.


    On Mac: `/Documents/Arduino/libraries`
    On Windows: `C:\Users\username\Documents\Arduino\libraries`

    Install ESP8266 Core Firmware

    Follow the instructions for downloading the Arduino ESP8266 core from Boards Manager. The SPISlave.h is newly added to the official SDK. NOTE: Per a comment in the forums: "the GUI only works if the binary is compiled using Arduino ESP library version 2.5.0".

    Select 'Adafruit Huzzah ESP8266 as Board

    If you followed the process in the previous link, and you will be able to from Tools->Board select Adafruit Huzzah ESP8266 from the ESP8266 Modules subsection. Then, select from Tools->Flash Size, 4M (1M SPIFFS).

    board_dropdown

    Select DefaultWifiShield.ino from Examples

    In the Arduino IDE go to Files-->Examples-->OpenBCI_Wifi-->DefaultWifiShield which will launch the default Wifi Shield firmware. NOTE You must upload ONLY the DefaultWifiShield Sketch!

    Compile Source Code with Arduino

    Restart your Arduino if you just installed all of the dependencies. Select Verify from the menu bar Sketch-->Verify/Compile.

    Compile Source Code with make

    While developing this firmware, we found it much better to use makeESPArduino which is a command line tool for building and compiling the firmware without having to use the Arduino IDE! Use the makeESPWifiDefault.mk file in the WiFi's github repo.

    Get the Serial Port of Programmer

    The correct serial port for your OpenBCI Dongle or FTDI friend will be


    * On Macs, this will be named **/dev/tty.usbserial-DN00nnnn** where the nnnn is a combination of numbers and letters specific to your programmer of choice.

    * On Windows, the serial port will be listed as a numbered COM port.

    * On Linux, it will be different.

    Connect WiFi Shield to Programmer

    Hook up the FTDI friend, OpenBCI Dongle, or other UART-USB programmer to the Wifi Shield. Don't power the Wifi shield through the FTDI friend.

    FTDI_FriendWifi Shield
    GNDGND
    RXTX
    TXRX

    Wifi to FTDI friend

    Isolate and Power WiFi Shield

    Next remove your wifi shield from the Cyton or Ganglion if it's not already.

    Remove your Wifi Shield from the Cyton/Ganglion board. Always use a spudger to remove your WiFi Shield from a Cyton or Ganglion.

    Wifi alone

    Plug a battery into the WiFi Shield and power the Shield by turning the power switch to the ON position.

    Plug in battery to the wifi shield

    Battery to wifi shield

    Second power the Wifi shield

    Battery to wifi shield

    Put WiFi Shield in Bootloader Mode

    Press and hold the PROG button.

    Wifi programming hold prog

    Press and release the RESET button while holding PROG.

    Wifi programming hold reset

    Wifi programming release reset

    Finally, release the PROG button.

    Wifi programming release reset

    You should see no lights on the WiFi Shield if it is in bootloading mode.

    Upload the code

    Now press upload in the Arduino IDE or execute the make -f makeESPDefault.mk flash to upload to the shield.

    - - + + \ No newline at end of file diff --git a/ThirdParty/WiFiShield/WiFiSDK/index.html b/ThirdParty/WiFiShield/WiFiSDK/index.html index 391ac9477..c69719298 100644 --- a/ThirdParty/WiFiShield/WiFiSDK/index.html +++ b/ThirdParty/WiFiShield/WiFiSDK/index.html @@ -12,15 +12,15 @@ OpenBCI Wifi SDK | OpenBCI Documentation - - + +
    Skip to main content

    OpenBCI Wifi SDK

    The purpose of this doc is to describe what's required to interface another micro-controller with the WiFi Shield.

    Prerequisites

    Please have the latest Arduino version downloaded and installed.

    Install OpenBCI Wifi Master

    There are many options for downloading the OpenBCI Wifi Master.

    From Arduino Library Manager (easiest!)

    Simply search for OpenBCI Wifi Master in the Arduino Library Manager. For help using the Library manager please checkout the well maintained Official Arduino Guide.

    Manual Installation

    1. Download the latest (or version of choice) from arduinolibraries.info.

    2. Unzip the folder and change the name to OpenBCI_Wifi_Master

    3. Move OpenBCI_Wifi_Master to:

      On Mac: /Documents/Arduino/libraries
      On Windows: C:\Users\username\Documents\Arduino\libraries

    If you're have trouble or want to learn more checkout the Official Arduino Guide for manual installation.

    Clone From Github

    Use a git client to clone the official repository for the OpenBCI_Wifi_Master_Library into your libraries folder.

    Sending Data to WiFi Shield

    Overview

    The WiFi Shield acts a SPI slave device to the Cyton or Ganglion. The max speed the ESP8266 can seem to handle is 10MHz. A SPISlave example we based our Wifi code on. To interact with this SPI slave library, (you wanted to use this WiFi Shield for some other reason...) you should look at the SPI Master example because the commands to get data vs read a status register are strictly defined and must be followed. The first constraint the Arduino ESP8266 SPI slave places on us is to always send 32 bytes per message. This library says that each packet must be 32 bytes, so that's where we begin....

    Byte Stream Format

    The first byte to send is the control byte. For streaming data, that goes on the TCP socket, send 0xCX (where X is 0-F in hex) as the control byte. In the OpenBCI_32bit_Library code base:


    /*
    * @description Writes channel data and axisData array to serial port in
    * the correct stream packet format.
    */
    void OpenBCI_32bit_Library::sendChannelDataWifi(void) {

    wifiStoreByte(OPENBCI_EOP_STND_ACCEL); // 0xC0 1 byte

    wifiStoreByte(sampleCounter); // 1 byte

    ADS_writeChannelDataWifi(); // 24 bytes

    accelWriteAxisDataWifi(); // 6 bytes

    wifiFlushBuffer(); // Flushes the buffer to the SPISlave ESP8266 device!

    sampleCounter++;

    }

    This code writes 32 bytes of data in the correct format and therefore as soon as it arrives at the WiFi Shield. The WiFi Shield will convert the 32 byte packet to the standard 33 byte binary format by moving the control byte 0xCn, where n is 0-F (hex), to the stop position and add add 0xA0 to the start position. This allows for a seamless integration with the tried and tested parsing systems already built for the Cyton. Important if you want to only send 20 bytes of data per packet, you still must send this 32 bytes with the proper start and stop bytes.

    - - + + \ No newline at end of file diff --git a/Troubleshooting/FTDI_Fix_Linux/index.html b/Troubleshooting/FTDI_Fix_Linux/index.html index 7e45c48ef..0e448cb15 100644 --- a/Troubleshooting/FTDI_Fix_Linux/index.html +++ b/Troubleshooting/FTDI_Fix_Linux/index.html @@ -12,13 +12,13 @@ FTDI Buffer Fix on Linux | OpenBCI Documentation - - + +
    Skip to main content

    FTDI Buffer Fix on Linux

    Summary

    This tutorial has been verified to work with the following Linux versions:

    • Ubuntu 18.04

    Step 1: Make sure FTDI driver is installed

    Make sure that the FTDI driver has been installed and you can connect to the Cyton.

    Step 2: Open latency_timer file

    Using file manager, open the latency_timer file. Found at:


    /sys/bus/usb-serial/devices/ttyUSB0/latency_timer

    where ttyUSB0 is the serial port name for the OpenBCI dongle.

    Step 2: Change 16 to 1

    The latency_timer should contain 16 by default. Change this to 1, and you're done!

    Step 3: Test OpenBCI GUI or BrainFlow

    Run the OpenBCI GUI or a BrainFlow binding, and you should see smoother data.

    - - + + \ No newline at end of file diff --git a/Troubleshooting/FTDI_Fix_Mac/index.html b/Troubleshooting/FTDI_Fix_Mac/index.html index e130e7f1f..94c32ed7b 100644 --- a/Troubleshooting/FTDI_Fix_Mac/index.html +++ b/Troubleshooting/FTDI_Fix_Mac/index.html @@ -12,8 +12,8 @@ FTDI Buffer Fix on OS X | OpenBCI Documentation - - + +
    @@ -25,7 +25,7 @@ followed by [CTRL] + c


    In vim:

    Hit the [esc] key to go into command mode. Then type :wq to save and quit.

    Step 12: reload the kernel extension


    sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext

    Step 13: make sure it's loaded


    kextstat | grep FTDI

    You should get a response that looks something like this:


    145 0 0xffffff7f82dce000 0x8000 0x8000 com.FTDI.driver.FTDIUSBSerialDriver (2.2.18) <118 37 5 4 3 1>

    Step 14: enjoy smoother streaming

    Open the OpenBCI Processing GUI (or other software), connect to your device, and begin streaming the data.


    Helpful Resources

    - - + + \ No newline at end of file diff --git a/Troubleshooting/FTDI_Fix_Windows/index.html b/Troubleshooting/FTDI_Fix_Windows/index.html index 45e67871a..8a1b7badf 100644 --- a/Troubleshooting/FTDI_Fix_Windows/index.html +++ b/Troubleshooting/FTDI_Fix_Windows/index.html @@ -12,14 +12,14 @@ FTDI Buffer Fix on Windows | OpenBCI Documentation - - + +
    Skip to main content

    FTDI Buffer Fix on Windows

    Tested on:

    • Windows 7
    • Windows XP
    • Windows 10

    I. Connecting the Board

    Device Manager

    Connect the OpenBCI dongle to the computer and power ON the OpenBCI board.

    1. Drivers

    1. If using Virtual Box: Enable FTDI FT231X USB UART on virtual box through Devices > USB Devices.
    2. Allow windows to try to install usb drivers.
    3. Open Device Manager from the start menu (or Control Panel > Hardware > Device Manager) and try to identify the OBCI board. It should be listed as either a COM port or an unidentified USB device.

    2. Unidentified device

    If the board is labeled as "Unidentified", follow the troubleshoot below:


    - Download [FTDI drivers](http://www.ftdichip.com/Drivers/VCP.htm).
    - Right click on Unidentified USB Device from the **Device Manager** tab and select **Update Driver Software**.
    - Select the "**Browse my Computer for Driver**" option and navigate to the FTDI download folder. Click on the folder and then click OK.
    - Your board should now be recognized as a COM port.

    3. Finish

    If everything went well, your OpenBCI Board should be showing up with a COM port number. If the number is not displayed next to the port name it should be visible in the properties of the port.

    To check it is, in fact, the OBCI board; connecting and disconnecting the Dongle should connect and disconnect the COM port.

    II. Latency Settings Fix

    Latency Fix

    The default FTDI latency is too large for EEG applications, making the incoming signal "choppy" and seem as if its accumulating packets for about a full second before releasing them all at the same time into the serial stream.

    The fix is easy. Simply right click the USB Serial Port of the OBCI board and go to Properties > Port Settings > Advanced and change the Latency Timer from the default 16 ms to 1 ms.

    Fixing this issue should make the incoming signal much more consistent in terms of packet time intervals.

    Available tools on Windows

    - - + + \ No newline at end of file diff --git a/Troubleshooting/GUI_Troubleshooting/index.html b/Troubleshooting/GUI_Troubleshooting/index.html index fbf2742ce..bf21b79d7 100644 --- a/Troubleshooting/GUI_Troubleshooting/index.html +++ b/Troubleshooting/GUI_Troubleshooting/index.html @@ -12,14 +12,14 @@ GUI Troubleshooting | OpenBCI Documentation - - + +
    Skip to main content

    GUI Troubleshooting

    The GUI Console Log

    • Want to know what's happening "under the hood" in the GUI?
      • Click the Console Log button in the top right (pictured below). gui console log button
    • Need even more information to debug a problem?
    • You can share the Console Log as text or a file on the Forums or GitHub. This is typically a requirement for new issues on GitHub.
    • You can use keyboard shortcuts within the Console Window to Open Log as Text(f), Copy Full Log Text(c), Copy Last Line (l), Jump to Last Line(j), Scroll Down(Down Key), and Scroll Up(Up Key).

    gui troubleshooting console window

    Issues Connecting & Starting Session

    1. If you receive an error in red at the bottom of the GUI while trying to connect to an OpenBCI board, try turning the board Off and back On.
    2. Also, unplug and plug the USB dongle for Cyton or BLED112 for Ganglion.
    3. Try to start a session again.
      • Cyton: If you still can't connect, try pressing the "AUTOSCAN" button once or twice.
      • Cyton+WiFi: Go through the WiFi Getting Started Guide. If this doesn't help, check the Forums or GitHub and make a new issue if one doesn't already exist. There are a number of issues that are currently being worked on.
      • Ganglion: The Ganglion board usually has fewer issues. If you can't get the Ganglion to connect to the GUI after trying the previous steps, you can email us at support@openbci.com or check GitHub.
    4. If your Cyton firmware is older than v3.0.0, you will need to update the firmware as outlined here. The latest Cyton firmware as of 2019 is v3.1.2.
    5. If nothing in the Docs, GitHub, or Forums are helpful, it's a good idea to email support@openbci.com or make a new issue on GitHub.

    Something Doesn't Look Right...

    1. Take a screenshot using tools provided by your operating system. Alternatively, you can turn on Expert Mode in the GUI and take a screenshot by pressing 'm' on your keyboard.
    2. Restart the GUI. If the same problem happens again, please make a new issue on GitHub.

    High DPI Scaling

    Troubleshooting Packet Loss

    Cyton

    Please, be advised that packet loss can occur in noisy environments, especially in university lab environments with multiple Cytons running. If you think you are experiencing packet loss, you can open the Console Log Window to confirm or deny packet loss and assess severity. Also, boards with low battery power may show packet loss and excessive noise.

    To fix this:

    • Use a USB extension cable or hub to make sure Cyton and Dongle are closer together.

    • Go to Manual Radio Configuration and try CHANGE CHAN. or AUTOSCAN as shown in the picture below. You can hover over these buttons with your mouse for a brief description. The Auto Connect button is disabled when using Manual Radio Config.

    • The current GUI now features packet loss interpolation. This makes filtered data much smoother and minimizes artefacts that would appear.

      GUI Cyton Manual Radio Configuration

    Ganglion

    Ganglion connections using the BLED 112 Dongle are usually very stable with low noise. If you experience packet loss, there may be an excess of BLE devices in the immediate area. Otherwise, try moving the Ganglion and Dongle closer together with a USB extension cable.

    Further troubleshooting

    If you're still having problems, search through the issues on GitHub or make a new issue.

    - - + + \ No newline at end of file diff --git a/Troubleshooting/MacOSGanglionBLEWorkaround/index.html b/Troubleshooting/MacOSGanglionBLEWorkaround/index.html index dd628dd1d..22d2b79d9 100644 --- a/Troubleshooting/MacOSGanglionBLEWorkaround/index.html +++ b/Troubleshooting/MacOSGanglionBLEWorkaround/index.html @@ -12,13 +12,13 @@ MacOS Ganglion BLE Workaround | OpenBCI Documentation - - + +
    Skip to main content

    MacOS Ganglion BLE Workaround

    In later versions of MacOS (generally MacOS 11+) there is an issue where Bluetooth permissions are not requested by the application. This prevents the embedded native BLE library from accessing the Bluetooth adapter and therefore Ganglion boards (and other Bluetooth devices) cannot be found. This issue appears to be related to application hardening requirements introduced in MacOS 10.14.5. Most importantly, the JDK 8 version that ships with Processing 3.5.4 and earlier is not notarized and therefore cannot request permissions from the OS.

    A workaround to the issue is updating the JDK in Processing to the latest version of JDK 8. This can be done with the following:

    curl -O -L --insecure https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u352-b08/OpenJDK8U-jdk_x64_mac_hotspot_8u352b08.tar.gz
    tar -xf OpenJDK8U-jdk_x64_mac_hotspot_8u352b08.tar.gz
    mv jdk8u352-b08 /Applications/Processing.app/Content/PlugIns/jdk1.8.0_202.jdk

    Then follow the instructions for running from the IDE.

    note

    Applications exported from Processing 3.5.4 do not appear to ask for Bluetooth permissions even if the JDK is updated before exporting. Processing 3.5.4 is no longer maintained so downstream fixes may exist in Processing 4.

    - - + + \ No newline at end of file diff --git a/Troubleshooting/TroubleshootingLanding/index.html b/Troubleshooting/TroubleshootingLanding/index.html index a027cc93c..1548f90dc 100644 --- a/Troubleshooting/TroubleshootingLanding/index.html +++ b/Troubleshooting/TroubleshootingLanding/index.html @@ -12,13 +12,13 @@ Troubleshooting Landing | OpenBCI Documentation - - + +
    Skip to main content
    - - + + \ No newline at end of file diff --git a/Troubleshooting/minimizingNoise/index.html b/Troubleshooting/minimizingNoise/index.html index a83338d23..f9d2efa25 100644 --- a/Troubleshooting/minimizingNoise/index.html +++ b/Troubleshooting/minimizingNoise/index.html @@ -12,13 +12,13 @@ Minimizing Noise | OpenBCI Documentation - - + +
    Skip to main content

    Minimizing Noise

    Are you getting "noisy" data from your device? There are several possible reasons for this. Let's go through some simple troubleshooting steps that resolve most issues.

    Get rid of AC noise

    Get rid of 60 Hz (or 50 Hz if you're in Europe or any country that operates on a 50 Hz power grid) using the OpenBCI GUI built-in notch filter. This does a good job at eliminating 60 Hz noise. You can adjust the notch filter by clicking the Filters button next to Start/Stop Data Stream then choose an option from the dropdown list. Additionally, if your board is on a table with any power cords or devices that are plugged into a wall outlet, move it to a location away from any electronic devices plugged into the wall. This will drastically reduce the alternating current (AC) influence on your signal.

    Notch Filter

    Stabilize your electrodes

    Make sure your electrode cables are steady. If you shake the electrodes that are dangling from your head/body, you'll notice that it severely affects the signals. This movement noise is something that could be greatly improved with active electrodes. When using the passive electrodes that come with the OpenBCI electrode starter kit, you have to be very careful to remain steady while using the system to produce the best signal. As a quick fix, binding all of the electrode cables together with a piece of electric tape secures them and minimizes cable movement. It is not as important to include any EMG/ECG channels in the bundle, since movement noise doesn't affect their signal as significantly.

    Stabilize Your Cables w/ Tape

    Ensure that your electrodes are securely connected

    Ensure that your electrodes are connected securely (especially your reference)!

    Make sure your OpenBCI hardware is streaming data properly

    Every so often, an error will occur with the wireless communication between your OpenBCI Dongle and board. If you've followed all of the steps above, and the data that you are seeing in the GUI interface is still illegible, try the following:

    1. Power down your board and unplug your USB Dongle.
    2. Plug back in your USB Dongle and power up your board in that order.
    3. Restart the GUI and start a new session.

    Check Cyton - GUI connection

    1. Open the GUI application and select Cyton
    2. Select the Manual option
    3. Unplug your dongle and select Refresh on the port selection
    4. Re-plug the dongle and select Refresh once again
    5. Select the serial port number (so that it's highlighted green)
    6. Hit AUTO-SCAN

    General tips for reducing noise (Cyton and Ganglion boards):

    • Plug the dongle into a USB hub or USB extension cord. This limits radio interference caused by computers.
    • Toggle on the filters in the OpenBCI GUI
    • Use the feet that came with the board
    • Use a fully charged battery
    • Turn off bluetooth devices in the room
    • Sit slightly away from the computer
    • Use the FTDI fix for Windows or Mac
    Additional Sources of Noise
    • AC power or extension cables on the floor
    • Conduits inside walls, floors or ceilings
    • Nearby wifi or cellular equipment
    • Laptop and desktop computers that have certain 'ground loop' or AC noise characteristics
    • Metal desks or other large metal objects nearby
    • LED, CFL or fluorescent lighting

    Further troubleshooting

    If you are still having issues, refer to the Forum for further troubleshooting techniques.

    - - + + \ No newline at end of file diff --git a/assets/js/69fc568b.00343185.js b/assets/js/69fc568b.00343185.js new file mode 100644 index 000000000..9c58ae57e --- /dev/null +++ b/assets/js/69fc568b.00343185.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[7282],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>f});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),u=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),p=u(n),m=o,f=p["".concat(c,".").concat(m)]||p[m]||d[m]||a;return n?r.createElement(f,i(i({ref:t},s),{},{components:n})):r.createElement(f,i({ref:t},s))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[p]="string"==typeof e?e:o,i[1]=l;for(var u=2;u{n.r(t),n.d(t,{contentTitle:()=>c,default:()=>m,frontMatter:()=>l,metadata:()=>u,toc:()=>s});var r=n(87462),o=n(63366),a=(n(67294),n(3905)),i=["components"],l={id:"Conduct",title:"Code of Conduct"},c=void 0,u={unversionedId:"FAQ/Conduct",id:"FAQ/Conduct",title:"Code of Conduct",description:"Our Pledge",source:"@site/docs/FAQ/Code_Of_Conduct.md",sourceDirName:"FAQ",slug:"/FAQ/Conduct",permalink:"/FAQ/Conduct",editUrl:"https://github.com/OpenBCI/Documentation/edit/master/website/docs/FAQ/Code_Of_Conduct.md",tags:[],version:"current",lastUpdatedAt:1690576132,formattedLastUpdatedAt:"7/28/2023",frontMatter:{id:"Conduct",title:"Code of Conduct"},sidebar:"docs",previous:{title:"Liability Policy",permalink:"/FAQ/Liability"}},s=[{value:"Our Pledge",id:"our-pledge",children:[],level:2},{value:"Our Standards",id:"our-standards",children:[],level:2},{value:"Enforcement",id:"enforcement",children:[],level:2},{value:"Attribution",id:"attribution",children:[],level:2}],p={toc:s},d="wrapper";function m(e){var t=e.components,n=(0,o.Z)(e,i);return(0,a.kt)(d,(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"our-pledge"},"Our Pledge"),(0,a.kt)("p",null,"In the interest of fostering an open and welcoming environment, we hope to provide a safe, welcoming, and warmly geeky environment for everybody, regardless of gender, sexual orientation, disability, ethnicity, socioeconomic status, and religion (or lack thereof)."),(0,a.kt)("h2",{id:"our-standards"},"Our Standards"),(0,a.kt)("p",null,"Examples of behavior that contributes to creating a positive environment\ninclude:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Using welcoming and inclusive language"),(0,a.kt)("li",{parentName:"ul"},"Being respectful of differing viewpoints and experiences"),(0,a.kt)("li",{parentName:"ul"},"Gracefully accepting constructive criticism"),(0,a.kt)("li",{parentName:"ul"},"Focusing on what is best for the community"),(0,a.kt)("li",{parentName:"ul"},"Showing empathy towards other community members")),(0,a.kt)("p",null,"Examples of unacceptable behavior by participants include:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"The use of sexualized language or imagery and unwelcome sexual attention or\nadvances"),(0,a.kt)("li",{parentName:"ul"},"Trolling, insulting/derogatory comments, and personal or political attacks"),(0,a.kt)("li",{parentName:"ul"},"Public or private harassment"),(0,a.kt)("li",{parentName:"ul"},"Publishing others' private information, such as a physical or electronic\naddress, without explicit permission"),(0,a.kt)("li",{parentName:"ul"},"Other conduct which could reasonably be considered inappropriate in a\nprofessional setting")),(0,a.kt)("h2",{id:"enforcement"},"Enforcement"),(0,a.kt)("p",null,"Instances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the team at ",(0,a.kt)("a",{parentName:"p",href:"mailto:contact@openbci.com"},"contact@openbci.com"),". All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately."),(0,a.kt)("p",null,"This Code of Conduct applies within all OpenBCI spaces."),(0,a.kt)("h2",{id:"attribution"},"Attribution"),(0,a.kt)("p",null,"This Code of Conduct is adapted from the ",(0,a.kt)("a",{parentName:"p",href:"http://contributor-covenant.org"},"Contributor Covenant"),", version 1.4,\navailable at ",(0,a.kt)("a",{parentName:"p",href:"https://www.contributor-covenant.org/version/1/4/code-of-conduct.html"},"https://www.contributor-covenant.org/version/1/4/code-of-conduct.html")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8ff634cd.8b4400a7.js b/assets/js/8ff634cd.8b4400a7.js deleted file mode 100644 index ebc36e4d0..000000000 --- a/assets/js/8ff634cd.8b4400a7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[672],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>m});var r=i(67294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,r)}return i}function a(e){for(var t=1;t=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var l=r.createContext({}),c=function(e){var t=r.useContext(l),i=t;return e&&(i="function"==typeof e?e(t):a(a({},t),e)),i},d=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var i=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),u=c(i),f=n,m=u["".concat(l,".").concat(f)]||u[f]||p[f]||o;return i?r.createElement(m,a(a({ref:t},d),{},{components:i})):r.createElement(m,a({ref:t},d))}));function m(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=i.length,a=new Array(o);a[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:n,a[1]=s;for(var c=2;c{i.r(t),i.d(t,{contentTitle:()=>l,default:()=>f,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var r=i(87462),n=i(63366),o=(i(67294),i(3905)),a=["components"],s={id:"Liability",title:"Liability Policy"},l=void 0,c={unversionedId:"FAQ/Liability",id:"FAQ/Liability",title:"Liability Policy",description:"Disclaimer of medical, clinical, or diagnostic use",source:"@site/docs/FAQ/Liability_Policy.md",sourceDirName:"FAQ",slug:"/FAQ/Liability",permalink:"/FAQ/Liability",editUrl:"https://github.com/OpenBCI/Documentation/edit/master/website/docs/FAQ/Liability_Policy.md",tags:[],version:"current",lastUpdatedAt:1627405574,formattedLastUpdatedAt:"7/27/2021",frontMatter:{id:"Liability",title:"Liability Policy"},sidebar:"docs",previous:{title:"RETURNS & REFUNDS",permalink:"/FAQ/Returns"}},d=[{value:"Disclaimer of medical, clinical, or diagnostic use",id:"disclaimer-of-medical-clinical-or-diagnostic-use",children:[],level:3},{value:"Limitations of Liability.",id:"limitations-of-liability",children:[],level:3},{value:"Governing Law/Dispute Resolution",id:"governing-lawdispute-resolution",children:[],level:3}],u={toc:d},p="wrapper";function f(e){var t=e.components,i=(0,n.Z)(e,a);return(0,o.kt)(p,(0,r.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"disclaimer-of-medical-clinical-or-diagnostic-use"},"Disclaimer of medical, clinical, or diagnostic use"),(0,o.kt)("p",null,"OpenBCI, Inc. provides the OpenBCI-trademarked products under the following conditions: This evaluation board/kit is intended for use for ENGINEERING DEVELOPMENT, DEMONSTRATION, OR EVALUATION PURPOSES ONLY and is not considered by OpenBCI, Inc. to be a finished end-product fit for general consumer use."),(0,o.kt)("p",null,"FDA approval is NOT required to use an EEG device for recording and research purposes, unless specifically required by your IRB or research\ninstitution."),(0,o.kt)("p",null,'All official OpenBCI products are designed and assembled in the United States. OpenBCI products are not medical, clinical, or diagnostic devices nor are they intended for medical diagnosis and are provided to you "as is," and we make no express or implied warranties whatsoever with respect to its functionality, operability, or use, including, without limitation, any implied warranties, fitness for a particular purpose, or infringement.'),(0,o.kt)("p",null,"OpenBCI boards are designed to take power only from low\xad-voltage DC sources, i.e. batteries. They do not take power from the \u201cgrid,\u201d from power outlets, USB ports, etc."),(0,o.kt)("h3",{id:"limitations-of-liability"},"Limitations of Liability."),(0,o.kt)("p",null,"Persons handling the product(s) must have electronics training and observe good engineering practice standards. As such, the goods being provided are not intended to be complete in terms of required design\xad, marketing\xad, and/or manufacturing \xadrelated protective considerations, including product safety and environmental measures typically found in end products that incorporate such semiconductor components or circuit boards. This evaluation board/kit does not fall within the scope of the European Union directives regarding electromagnetic compatibility, restricted substances (RoHS), recycling (WEEE), FCC, CE or UL, and therefore may not meet the technical requirements of these directives or other related directives."),(0,o.kt)("p",null,"We expressly disclaim any liability whatsoever for any direct, indirect, consequential, incidental or special damages, including, without limitation, lost revenues, lost profits, losses resulting from business interruption or loss of data, regardless of the form of action or legal theory under which the liability may be asserted, even if advised of the possibility of such damages."),(0,o.kt)("p",null,"IN NO EVENT WILL OPENBCI BE LIABLE TO END USER FOR SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, PUNITIVE, OR OTHER INDIRECT DAMAGES, OR FOR LOSS OF PROFITS, LOSS OF DATA OR LOSS OF USE, ARISING OUT OF THE MANUFACTURE, SALE, SUPPLYING OR FAILURE OR DELAY IN SUPPLYING OF THE PRODUCTS OR SERVICES RELATED THERETO, WHETHER BASED UPON WARRANTY, CONTRACT, TORT, STRICT LIABILITY OR OTHERWISE, EVEN IF OPENBCI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR LOSSES.\nUNDER NO CIRCUMSTANCES WILL OPENBCI\u2019S TOTAL LIABILITY TO END USER FROM ANY AND ALL CAUSES (INCLUDING NEGLIGENCE) EXCEED THE TOTAL AMOUNT PAID BY END USER FOR THE PRODUCTS."),(0,o.kt)("h3",{id:"governing-lawdispute-resolution"},"Governing Law/Dispute Resolution"),(0,o.kt)("p",null,"These terms and your use of the Products shall be governed by the law of the State of New York, U.S.A.. Any disputes arising from these terms or your use of the Products shall be heard in the state or federal courts located in New York, New York, U.S.A."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8ff634cd.eff73510.js b/assets/js/8ff634cd.eff73510.js new file mode 100644 index 000000000..731dbfc40 --- /dev/null +++ b/assets/js/8ff634cd.eff73510.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[672],{3905:(e,t,i)=>{i.d(t,{Zo:()=>d,kt:()=>m});var r=i(67294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,r)}return i}function a(e){for(var t=1;t=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var s=r.createContext({}),c=function(e){var t=r.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):a(a({},t),e)),i},d=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var i=e.components,n=e.mdxType,o=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=c(i),f=n,m=u["".concat(s,".").concat(f)]||u[f]||p[f]||o;return i?r.createElement(m,a(a({ref:t},d),{},{components:i})):r.createElement(m,a({ref:t},d))}));function m(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=i.length,a=new Array(o);a[0]=f;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:n,a[1]=l;for(var c=2;c{i.r(t),i.d(t,{contentTitle:()=>s,default:()=>f,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var r=i(87462),n=i(63366),o=(i(67294),i(3905)),a=["components"],l={id:"Liability",title:"Liability Policy"},s=void 0,c={unversionedId:"FAQ/Liability",id:"FAQ/Liability",title:"Liability Policy",description:"Disclaimer of medical, clinical, or diagnostic use",source:"@site/docs/FAQ/Liability_Policy.md",sourceDirName:"FAQ",slug:"/FAQ/Liability",permalink:"/FAQ/Liability",editUrl:"https://github.com/OpenBCI/Documentation/edit/master/website/docs/FAQ/Liability_Policy.md",tags:[],version:"current",lastUpdatedAt:1627405574,formattedLastUpdatedAt:"7/27/2021",frontMatter:{id:"Liability",title:"Liability Policy"},sidebar:"docs",previous:{title:"RETURNS & REFUNDS",permalink:"/FAQ/Returns"},next:{title:"Code of Conduct",permalink:"/FAQ/Conduct"}},d=[{value:"Disclaimer of medical, clinical, or diagnostic use",id:"disclaimer-of-medical-clinical-or-diagnostic-use",children:[],level:3},{value:"Limitations of Liability.",id:"limitations-of-liability",children:[],level:3},{value:"Governing Law/Dispute Resolution",id:"governing-lawdispute-resolution",children:[],level:3}],u={toc:d},p="wrapper";function f(e){var t=e.components,i=(0,n.Z)(e,a);return(0,o.kt)(p,(0,r.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"disclaimer-of-medical-clinical-or-diagnostic-use"},"Disclaimer of medical, clinical, or diagnostic use"),(0,o.kt)("p",null,"OpenBCI, Inc. provides the OpenBCI-trademarked products under the following conditions: This evaluation board/kit is intended for use for ENGINEERING DEVELOPMENT, DEMONSTRATION, OR EVALUATION PURPOSES ONLY and is not considered by OpenBCI, Inc. to be a finished end-product fit for general consumer use."),(0,o.kt)("p",null,"FDA approval is NOT required to use an EEG device for recording and research purposes, unless specifically required by your IRB or research\ninstitution."),(0,o.kt)("p",null,'All official OpenBCI products are designed and assembled in the United States. OpenBCI products are not medical, clinical, or diagnostic devices nor are they intended for medical diagnosis and are provided to you "as is," and we make no express or implied warranties whatsoever with respect to its functionality, operability, or use, including, without limitation, any implied warranties, fitness for a particular purpose, or infringement.'),(0,o.kt)("p",null,"OpenBCI boards are designed to take power only from low\xad-voltage DC sources, i.e. batteries. They do not take power from the \u201cgrid,\u201d from power outlets, USB ports, etc."),(0,o.kt)("h3",{id:"limitations-of-liability"},"Limitations of Liability."),(0,o.kt)("p",null,"Persons handling the product(s) must have electronics training and observe good engineering practice standards. As such, the goods being provided are not intended to be complete in terms of required design\xad, marketing\xad, and/or manufacturing \xadrelated protective considerations, including product safety and environmental measures typically found in end products that incorporate such semiconductor components or circuit boards. This evaluation board/kit does not fall within the scope of the European Union directives regarding electromagnetic compatibility, restricted substances (RoHS), recycling (WEEE), FCC, CE or UL, and therefore may not meet the technical requirements of these directives or other related directives."),(0,o.kt)("p",null,"We expressly disclaim any liability whatsoever for any direct, indirect, consequential, incidental or special damages, including, without limitation, lost revenues, lost profits, losses resulting from business interruption or loss of data, regardless of the form of action or legal theory under which the liability may be asserted, even if advised of the possibility of such damages."),(0,o.kt)("p",null,"IN NO EVENT WILL OPENBCI BE LIABLE TO END USER FOR SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, PUNITIVE, OR OTHER INDIRECT DAMAGES, OR FOR LOSS OF PROFITS, LOSS OF DATA OR LOSS OF USE, ARISING OUT OF THE MANUFACTURE, SALE, SUPPLYING OR FAILURE OR DELAY IN SUPPLYING OF THE PRODUCTS OR SERVICES RELATED THERETO, WHETHER BASED UPON WARRANTY, CONTRACT, TORT, STRICT LIABILITY OR OTHERWISE, EVEN IF OPENBCI HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR LOSSES.\nUNDER NO CIRCUMSTANCES WILL OPENBCI\u2019S TOTAL LIABILITY TO END USER FROM ANY AND ALL CAUSES (INCLUDING NEGLIGENCE) EXCEED THE TOTAL AMOUNT PAID BY END USER FOR THE PRODUCTS."),(0,o.kt)("h3",{id:"governing-lawdispute-resolution"},"Governing Law/Dispute Resolution"),(0,o.kt)("p",null,"These terms and your use of the Products shall be governed by the law of the State of New York, U.S.A.. Any disputes arising from these terms or your use of the Products shall be heard in the state or federal courts located in New York, New York, U.S.A."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.924ed571.js b/assets/js/935f2afb.924ed571.js new file mode 100644 index 000000000..e4ef7414f --- /dev/null +++ b/assets/js/935f2afb.924ed571.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"docs":[{"type":"category","collapsed":true,"collapsible":true,"label":"Welcome to OpenBCI","items":[{"type":"link","label":"Welcome to the OpenBCI Community","href":"/","docId":"Welcome"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Getting Started","items":[{"type":"link","label":"Getting Started","href":"/GettingStarted/GettingStartedLanding","docId":"GettingStarted/GettingStartedLanding"},{"type":"category","label":"Boards","items":[{"type":"link","label":"Cyton Getting Started Guide","href":"/GettingStarted/Boards/CytonGS","docId":"GettingStarted/Boards/CytonGS"},{"type":"link","label":"Daisy Getting Started Guide","href":"/GettingStarted/Boards/DaisyGS","docId":"GettingStarted/Boards/DaisyGS"},{"type":"link","label":"Ganglion Getting Started Guide","href":"/GettingStarted/Boards/GanglionGS","docId":"GettingStarted/Boards/GanglionGS"},{"type":"link","label":"WiFi Shield Getting Started Guide","href":"/GettingStarted/Boards/WiFiGS","docId":"GettingStarted/Boards/WiFiGS"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Biosensing Setups","items":[{"type":"link","label":"Setting up for EEG","href":"/GettingStarted/Biosensing-Setups/EEGSetup","docId":"GettingStarted/Biosensing-Setups/EEGSetup"},{"type":"link","label":"Setting up for ECG","href":"/GettingStarted/Biosensing-Setups/ECGSetup","docId":"GettingStarted/Biosensing-Setups/ECGSetup"},{"type":"link","label":"Setting up for EMG","href":"/GettingStarted/Biosensing-Setups/EMGSetup","docId":"GettingStarted/Biosensing-Setups/EMGSetup"},{"type":"link","label":"Setting up for EEG, EMG, and ECG at the same time","href":"/GettingStarted/Biosensing-Setups/ExGSetup","docId":"GettingStarted/Biosensing-Setups/ExGSetup"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Community","items":[{"type":"link","label":"Welcome to the OpenBCI Community","href":"/GettingStarted/Community/Community","docId":"GettingStarted/Community/Community"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Documentation","items":[{"type":"link","label":"Editing Docs Guide","href":"/GettingStarted/Documentation/DocEdits","docId":"GettingStarted/Documentation/DocEdits"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Cyton Board","items":[{"type":"link","label":"Cyton Board","href":"/Cyton/CytonLanding","docId":"Cyton/CytonLanding"},{"type":"link","label":"Cyton Specs","href":"/Cyton/CytonSpecs","docId":"Cyton/CytonSpecs"},{"type":"link","label":"Cyton Data Format","href":"/Cyton/CytonDataFormat","docId":"Cyton/CytonDataFormat"},{"type":"link","label":"Cyton Board SDK","href":"/Cyton/CytonSDK","docId":"Cyton/CytonSDK"},{"type":"link","label":"Cyton Board Programming Tutorial","href":"/Cyton/CytonProgram","docId":"Cyton/CytonProgram"},{"type":"link","label":"Cyton Radios Programming Tutorial","href":"/Cyton/CytonRadios","docId":"Cyton/CytonRadios"},{"type":"link","label":"External Trigger on OpenBCI Cyton Board","href":"/Cyton/CytonExternal","docId":"Cyton/CytonExternal"},{"type":"link","label":"Using SD Card with Cyton and CytonDaisy Board","href":"/Cyton/CytonSDCard","docId":"Cyton/CytonSDCard"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Ganglion Board","items":[{"type":"link","label":"Ganglion Board","href":"/Ganglion/GanglionLanding","docId":"Ganglion/GanglionLanding"},{"type":"link","label":"Ganglion Specs","href":"/Ganglion/GanglionSpecs","docId":"Ganglion/GanglionSpecs"},{"type":"link","label":"Ganglion Data Format","href":"/Ganglion/GanglionDataFormat","docId":"Ganglion/GanglionDataFormat"},{"type":"link","label":"Ganglion SDK","href":"/Ganglion/GanglionSDK","docId":"Ganglion/GanglionSDK"},{"type":"link","label":"Ganglion Programming Tutorial","href":"/Ganglion/GanglionProgram","docId":"Ganglion/GanglionProgram"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Headwear & Electrodes","items":[{"type":"link","label":"Add Ons","href":"/AddOns/AddOnLanding","docId":"AddOns/AddOnLanding"},{"type":"category","label":"Headwear","items":[{"type":"link","label":"Ultracortex Mark IV","href":"/AddOns/Headwear/MarkIV","docId":"AddOns/Headwear/MarkIV"},{"type":"link","label":"OpenBCI EEG Headband Kit Guide","href":"/AddOns/Headwear/HeadBand","docId":"AddOns/Headwear/HeadBand"},{"type":"link","label":"Electrode Cap Getting Started Guide","href":"/AddOns/Headwear/ElectrodeCap","docId":"AddOns/Headwear/ElectrodeCap"},{"type":"link","label":"Gelfree Electrode Cap Guide","href":"/AddOns/Headwear/GelfreeElectrodeCap","docId":"AddOns/Headwear/GelfreeElectrodeCap"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Electrodes","items":[{"type":"link","label":"Electrode Guide","href":"/AddOns/Electrodes/ElectrodesLanding","docId":"AddOns/Electrodes/ElectrodesLanding"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Third-Party Hardware","items":[{"type":"link","label":"Third-Party Hardware","href":"/ThirdParty/ThirdPartyLanding","docId":"ThirdParty/ThirdPartyLanding"},{"type":"category","label":"EmotiBit","items":[{"type":"link","label":"EmotiBit Guide","href":"/ThirdParty/EmotiBit/EmotiBit_Guide","docId":"ThirdParty/EmotiBit/EmotiBit_Guide"}],"collapsible":true,"collapsed":true},{"type":"category","label":"IDUN Dryode","items":[{"type":"link","label":"IDUN Dryode","href":"/ThirdParty/IDUN_Dryode/Dryode","docId":"ThirdParty/IDUN_Dryode/Dryode"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Myoware","items":[{"type":"link","label":"MyoWare OpenBCI Integration (Cyton Board)","href":"/ThirdParty/Myoware/MyoWareCyton","docId":"ThirdParty/Myoware/MyoWareCyton"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Pulse Sensor","items":[{"type":"link","label":"Pulse Sensor Guide","href":"/ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing","docId":"ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing"}],"collapsible":true,"collapsed":true},{"type":"category","label":"ThinkPulse","items":[{"type":"link","label":"ThinkPulse Getting Started Guide","href":"/ThirdParty/ThinkPulse/ThinkPulse","docId":"ThirdParty/ThinkPulse/ThinkPulse"}],"collapsible":true,"collapsed":true},{"type":"category","label":"WiFi Shield","items":[{"type":"link","label":"OpenBCI WiFi","href":"/ThirdParty/WiFiShield/WiFiLanding","docId":"ThirdParty/WiFiShield/WiFiLanding"},{"type":"link","label":"Wifi Shield Programming Tutorial","href":"/ThirdParty/WiFiShield/WiFiProgam","docId":"ThirdParty/WiFiShield/WiFiProgam"},{"type":"link","label":"OpenBCI WiFi Shield API","href":"/ThirdParty/WiFiShield/WiFiAPI","docId":"ThirdParty/WiFiShield/WiFiAPI"},{"type":"link","label":"OpenBCI Wifi SDK","href":"/ThirdParty/WiFiShield/WiFiSDK","docId":"ThirdParty/WiFiShield/WiFiSDK"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Software","items":[{"type":"link","label":"Compatible Software","href":"/Software/SoftwareLanding","docId":"Software/SoftwareLanding"},{"type":"category","label":"Developed By OpenBCI","items":[{"type":"link","label":"The OpenBCI GUI","href":"/Software/OpenBCISoftware/GUIDocs","docId":"Software/OpenBCISoftware/GUIDocs"},{"type":"link","label":"GUI Widget Guide","href":"/Software/OpenBCISoftware/GUIWidgets","docId":"Software/OpenBCISoftware/GUIWidgets"},{"type":"link","label":"NeuroFly Toolkit","href":"/Software/OpenBCISoftware/NeuroFly_Toolkit","docId":"Software/OpenBCISoftware/NeuroFly_Toolkit"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Compatible Third Party Software","items":[{"type":"link","label":"MATLAB","href":"/Software/CompatibleThirdPartySoftware/Matlab","docId":"Software/CompatibleThirdPartySoftware/Matlab"},{"type":"link","label":"Neuromore","href":"/Software/CompatibleThirdPartySoftware/Neuromore","docId":"Software/CompatibleThirdPartySoftware/Neuromore"},{"type":"link","label":"OpenViBE","href":"/Software/CompatibleThirdPartySoftware/OpenVibe","docId":"Software/CompatibleThirdPartySoftware/OpenVibe"},{"type":"link","label":"Lab Streaming Layer (LSL)","href":"/Software/CompatibleThirdPartySoftware/LSL","docId":"Software/CompatibleThirdPartySoftware/LSL"},{"type":"link","label":"BrainBay","href":"/Software/CompatibleThirdPartySoftware/BrainBay","docId":"Software/CompatibleThirdPartySoftware/BrainBay"},{"type":"link","label":"BioEra","href":"/Software/CompatibleThirdPartySoftware/BioEra","docId":"Software/CompatibleThirdPartySoftware/BioEra"},{"type":"link","label":"VirtualBox Windows Guide","href":"/Software/CompatibleThirdPartySoftware/VirtualBox","docId":"Software/CompatibleThirdPartySoftware/VirtualBox"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"For Developers","items":[{"type":"link","label":"For Developers","href":"/ForDevelopers/ForDevelopersLanding","docId":"ForDevelopers/ForDevelopersLanding"},{"type":"link","label":"Software Development","href":"/ForDevelopers/SoftwareDevelopment","docId":"ForDevelopers/SoftwareDevelopment"},{"type":"link","label":"Firmware Development","href":"/ForDevelopers/FirmwareDevelopment","docId":"ForDevelopers/FirmwareDevelopment"},{"type":"link","label":"Hardware Development","href":"/ForDevelopers/HardwareDevelopment","docId":"ForDevelopers/HardwareDevelopment"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Deprecated Documents","items":[{"type":"link","label":"Deprecated Docs","href":"/Deprecated/DeprecatedLanding","docId":"Deprecated/DeprecatedLanding"},{"type":"link","label":"Spiderclaw V1 & V2 (deprecated)","href":"/Deprecated/SpiderclawDep","docId":"Deprecated/SpiderclawDep"},{"type":"link","label":"OpenBCI 8bit Board (no longer in production)","href":"/Deprecated/8bitBoardDep","docId":"Deprecated/8bitBoardDep"},{"type":"link","label":"Ultracortex Mark 1","href":"/Deprecated/UltracortexMark1Dep","docId":"Deprecated/UltracortexMark1Dep"},{"type":"link","label":"Ultracortex Mark 2","href":"/Deprecated/UltracortexMark2Dep","docId":"Deprecated/UltracortexMark2Dep"},{"type":"link","label":"Ultracortex Mark 2","href":"/Deprecated/UltracortexMark2Dep","docId":"Deprecated/UltracortexMark2Dep"},{"type":"link","label":"Ultracortex Mark III Nova and Supernova","href":"/Deprecated/UltracortexMark3_NovaDep","docId":"Deprecated/UltracortexMark3_NovaDep"},{"type":"link","label":"Ultracortex Mark III","href":"/Deprecated/MarkIII","docId":"Deprecated/MarkIII"},{"type":"link","label":"Python and OpenBCI","href":"/Deprecated/Python","docId":"Deprecated/Python"},{"type":"link","label":"OpenBCI Hub","href":"/Deprecated/Hub","docId":"Deprecated/Hub"},{"type":"link","label":"MyoWare OpenBCI Integration (Cyton Board)","href":"/Deprecated/MyoCyton","docId":"Deprecated/MyoCyton"},{"type":"link","label":"MyoWare OpenBCI Integration (Ganglion Board)","href":"/Deprecated/MyoGanglion","docId":"Deprecated/MyoGanglion"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Troubleshooting","items":[{"type":"link","label":"Troubleshooting Landing","href":"/Troubleshooting/TroubleshootingLanding","docId":"Troubleshooting/TroubleshootingLanding"},{"type":"link","label":"Minimizing Noise","href":"/Troubleshooting/minimizingNoise","docId":"Troubleshooting/minimizingNoise"},{"type":"link","label":"GUI Troubleshooting","href":"/Troubleshooting/GUI_Troubleshooting","docId":"Troubleshooting/GUI_Troubleshooting"},{"type":"link","label":"FTDI Buffer Fix on Linux","href":"/Troubleshooting/FTDI_Fix_Linux","docId":"Troubleshooting/FTDI_Fix_Linux"},{"type":"link","label":"FTDI Buffer Fix on OS X","href":"/Troubleshooting/FTDI_Fix_Mac","docId":"Troubleshooting/FTDI_Fix_Mac"},{"type":"link","label":"FTDI Buffer Fix on Windows","href":"/Troubleshooting/FTDI_Fix_Windows","docId":"Troubleshooting/FTDI_Fix_Windows"},{"type":"link","label":"MacOS Ganglion BLE Workaround","href":"/Troubleshooting/MacOSGanglionBLEWorkaround","docId":"Troubleshooting/MacOSGanglionBLEWorkaround"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Example Projects","items":[{"type":"link","label":"Example Projects","href":"/Examples/ExamplesLanding","docId":"Examples/ExamplesLanding"},{"type":"category","label":"Experiments","items":[{"type":"link","label":"Puppies and Kittens Experiment","href":"/Examples/VideoExperiment","docId":"Examples/VideoExperiment"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Community Page Projects","items":[{"type":"link","label":"Community Page Projects","href":"/Examples/CommunityPageProjects","docId":"Examples/CommunityPageProjects"}],"collapsible":true,"collapsed":true},{"type":"category","label":"EMG Projects and Tutorials","items":[{"type":"link","label":"EMG Scrolling","href":"/Examples/EMGProjects/EMGscrolling","docId":"Examples/EMGProjects/EMGscrolling"},{"type":"link","label":"EMG-controlled Music","href":"/Examples/EMGProjects/EMGmusic","docId":"Examples/EMGProjects/EMGmusic"},{"type":"link","label":"EMG-controlled Slideshow","href":"/Examples/EMGProjects/EMGslideshow","docId":"Examples/EMGProjects/EMGslideshow"},{"type":"link","label":"EMG-controlled LED","href":"/Examples/EMGProjects/EMG_LED","docId":"Examples/EMGProjects/EMG_LED"},{"type":"link","label":"EMG Chrome Dino Game","href":"/Examples/EMGProjects/EMG_Chrome_Dino_Game","docId":"Examples/EMGProjects/EMG_Chrome_Dino_Game"},{"type":"link","label":"EMG-controlled Tetris","href":"/Examples/EMGProjects/EMG_Tetris","docId":"Examples/EMGProjects/EMG_Tetris"},{"type":"link","label":"EMG-controlled Piano","href":"/Examples/EMGProjects/EMGpiano","docId":"Examples/EMGProjects/EMGpiano"}],"collapsible":true,"collapsed":true},{"type":"category","label":"EEG Projects and Tutorials","items":[{"type":"link","label":"Send Focus Data from GUI to Arduino","href":"/Examples/EEGProjects/FocusArduino","docId":"Examples/EEGProjects/FocusArduino"},{"type":"link","label":"Motor Imagery","href":"/Examples/EEGProjects/MotorImagery","docId":"Examples/EEGProjects/MotorImagery"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"FAQ","items":[{"type":"category","label":"FAQ","items":[{"type":"link","label":"Frequently Asked Questions","href":"/FAQ/FAQLanding","docId":"FAQ/FAQLanding"},{"type":"link","label":"General Frequently Asked Questions","href":"/FAQ/GenFAQ","docId":"FAQ/GenFAQ"},{"type":"link","label":"How OpenBCI products go together?","href":"/FAQ/HowProductsGoTogether","docId":"FAQ/HowProductsGoTogether"},{"type":"link","label":"Hardware & Software","href":"/FAQ/HardFAQ","docId":"FAQ/HardFAQ"},{"type":"link","label":"Purchases & Payment Processing","href":"/FAQ/PaymentFAQ","docId":"FAQ/PaymentFAQ"},{"type":"link","label":"Shipping & Taxes","href":"/FAQ/ShippingFAQ","docId":"FAQ/ShippingFAQ"},{"type":"link","label":"Docs Website Update","href":"/FAQ/DocsUpdate","docId":"FAQ/DocsUpdate"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Policies","items":[{"type":"link","label":"OpenBCI Cookie Policy","href":"/FAQ/Cookie","docId":"FAQ/Cookie"},{"type":"link","label":"Privacy & Security","href":"/FAQ/Privacy","docId":"FAQ/Privacy"},{"type":"link","label":"RETURNS & REFUNDS","href":"/FAQ/Returns","docId":"FAQ/Returns"},{"type":"link","label":"Liability Policy","href":"/FAQ/Liability","docId":"FAQ/Liability"},{"type":"link","label":"Code of Conduct","href":"/FAQ/Conduct","docId":"FAQ/Conduct"}],"collapsible":true,"collapsed":true}]}]},"docs":{"AddOns/AddOnLanding":{"id":"AddOns/AddOnLanding","title":"Add Ons","description":"This section summarizes the headwear and electrodes that goes with OpenBCI boards to help gather data.","sidebar":"docs"},"AddOns/Electrodes/ElectrodesLanding":{"id":"AddOns/Electrodes/ElectrodesLanding","title":"Electrode Guide","description":"OpenBCI Boards are compatible with a variety of different electrodes.","sidebar":"docs"},"AddOns/Headwear/ElectrodeCap":{"id":"AddOns/Headwear/ElectrodeCap","title":"Electrode Cap Getting Started Guide","description":"This is a guide to setting up and cleaning your OpenBCI Electrode Cap. Please consult the Electrode Cap","sidebar":"docs"},"AddOns/Headwear/GelfreeElectrodeCap":{"id":"AddOns/Headwear/GelfreeElectrodeCap","title":"Gelfree Electrode Cap Guide","description":"This is a guide to setting up and cleaning your OpenBCI Gelfree Electrode Cap. Please consult the Gelfree Electrode Cap","sidebar":"docs"},"AddOns/Headwear/HeadBand":{"id":"AddOns/Headwear/HeadBand","title":"OpenBCI EEG Headband Kit Guide","description":"Now available in our shop!","sidebar":"docs"},"AddOns/Headwear/MarkIV":{"id":"AddOns/Headwear/MarkIV","title":"Ultracortex Mark IV","description":"Development Period: January 2016 Through the Present","sidebar":"docs"},"Cyton/CytonDataFormat":{"id":"Cyton/CytonDataFormat","title":"Cyton Data Format","description":"This discussion of the OpenBCI data format only applies to OpenBCI v1 (2014-2016) and v2.0.0 (Fall 2016). For OpenBCI Cyton, the OpenBCI board contains either a ChipKIT or ATmega microcontroller that can both be programmed through the Arduino IDE. The Cyton board has an on-board RFDuino radio module acting as a \\"Device\\". The Cyton system includes a USB dongle for the PC, which acts as the RFDuino \\"Host\\". The format of the OpenBCI data as seen on the PC is defined by a combination of the Arduino code on the Cyton board and of the RFDuino code running on the Host. So, if you don\'t like the data format defined here, feel free to change it! For more info on the v2 firmware, see these Notes On Updating and Using v2.0.0 Cyton Firmware. There is also further information on controlling the OpenBCI Cyton on our OpenBCI Cyton SDK page.","sidebar":"docs"},"Cyton/CytonExternal":{"id":"Cyton/CytonExternal","title":"External Trigger on OpenBCI Cyton Board","description":"Sometimes, when studying EEG or other biopotential signals, you will want to have precise timing between external events or stimulus and the data stream. For example, if you are working with P300 waves it is necessary to know the exact time that the signal was presented to the subject in order to look for the tell-tale brain wave that happens about 300mS after the stimulus.","sidebar":"docs"},"Cyton/CytonLanding":{"id":"Cyton/CytonLanding","title":"Cyton Board","description":"Buy it!","sidebar":"docs"},"Cyton/CytonProgram":{"id":"Cyton/CytonProgram","title":"Cyton Board Programming Tutorial","description":"Note, you do not need to do any board programming if you want to use the Cyton out-of-the-box. All OpenBCI boards ship already programmed, i.e. with firmware uploaded. Email support@openbci.com before attempting to update or alter board firmware, or if you think there is an issue with your board. DO NOT attempt to upload firmware to your board unless specifically instructed to do so.","sidebar":"docs"},"Cyton/CytonRadios":{"id":"Cyton/CytonRadios","title":"Cyton Radios Programming Tutorial","description":"Note, you do not need to do any board programming if you want to use the Cyton and Dongle out-of-the-box. All OpenBCI boards ship already programmed, i.e. with firmware uploaded. Email support@openbci.com before attempting to update or alter board firmware, or if you think there is an issue with your board. DO NOT attempt to upload firmware to your Cyton board or dongle unless specifically instructed to do so.","sidebar":"docs"},"Cyton/CytonSDCard":{"id":"Cyton/CytonSDCard","title":"Using SD Card with Cyton and CytonDaisy Board","description":"Overview","sidebar":"docs"},"Cyton/CytonSDK":{"id":"Cyton/CytonSDK","title":"Cyton Board SDK","description":"The OpenBCI Cyton boards communicate using a byte string (mostly ASCII) command protocol. This Doc covers command use for the OpenBCI Cyton and 8bit boards. Some of the commands are board specific, where noted. Further this Doc covers the commands needed in order to alter the radio system. There have been several iterations of the firmware, the 8bit board runs v0, while the Cyton runs v1 and Boards shipped as of Fall 2016 run v2.0.0. v3.0.0 will begin shipping with boards in August of 2017.","sidebar":"docs"},"Cyton/CytonSpecs":{"id":"Cyton/CytonSpecs","title":"Cyton Specs","description":"BUY IT!","sidebar":"docs"},"Deprecated/8bitBoardDep":{"id":"Deprecated/8bitBoardDep","title":"OpenBCI 8bit Board (no longer in production)","description":"8bit Board Specs:","sidebar":"docs"},"Deprecated/DeprecatedLanding":{"id":"Deprecated/DeprecatedLanding","title":"Deprecated Docs","description":"This directory houses all deprecated documentation.","sidebar":"docs"},"Deprecated/Hub":{"id":"Deprecated/Hub","title":"OpenBCI Hub","description":"THIS SOFTWARE HAS BEEN DEPRECATED AND IS NO LONGER IN ACTIVE DEVELOPMENT.","sidebar":"docs"},"Deprecated/MarkIII":{"id":"Deprecated/MarkIII","title":"Ultracortex Mark III","description":"Development Period: June 2016","sidebar":"docs"},"Deprecated/MyoCyton":{"id":"Deprecated/MyoCyton","title":"MyoWare OpenBCI Integration (Cyton Board)","description":"THIS HARDWARE VERSION HAS BEEN DEPRECATED AND IS NO LONGER IN PRODUCTION.","sidebar":"docs"},"Deprecated/MyoGanglion":{"id":"Deprecated/MyoGanglion","title":"MyoWare OpenBCI Integration (Ganglion Board)","description":"THIS HARDWARE VERSION HAS BEEN DEPRECATED AND IS NO LONGER IN PRODUCTION.","sidebar":"docs"},"Deprecated/Python":{"id":"Deprecated/Python","title":"Python and OpenBCI","description":"THIS DOCUMENT HAS BEEN DEPRECATED. PLEASE REFER TO \\"FOR DEVELOPERS\\" SECTION FOR INFORMATION ON BRAINFLOW-PYTHON.","sidebar":"docs"},"Deprecated/SpiderclawDep":{"id":"Deprecated/SpiderclawDep","title":"Spiderclaw V1 & V2 (deprecated)","description":"Check out the following blog post (recently re-posted), for a detailed guide on the V1 & V2 Spiderclaw designs, as well as links to the relevant .stl, .obj, and Autodesk Maya files for Spiderclaw V1 and V2.","sidebar":"docs"},"Deprecated/UltracortexMark1Dep":{"id":"Deprecated/UltracortexMark1Dep","title":"Ultracortex Mark 1","description":"Files related to the ultracortex, the 3D-printable EEG headset compatible with OpenBCI (currently under development).","sidebar":"docs"},"Deprecated/UltracortexMark2Dep":{"id":"Deprecated/UltracortexMark2Dep","title":"Ultracortex Mark 2","description":"image","sidebar":"docs"},"Deprecated/UltracortexMark3_NovaDep":{"id":"Deprecated/UltracortexMark3_NovaDep","title":"Ultracortex Mark III Nova and Supernova","description":"Development Period: June 2016","sidebar":"docs"},"Deprecated/UltracortexMark3Dep":{"id":"Deprecated/UltracortexMark3Dep","title":"Ultracortex Mark 3","description":"Development Period: July 2015 \u2014 September 2015"},"Examples/CommunityPageProjects":{"id":"Examples/CommunityPageProjects","title":"Community Page Projects","description":"Head over to the Community Page for project tutorials contributed by OpenBCI Community members! Use the \\"tutorials\\" tag to filter.","sidebar":"docs"},"Examples/EEGProjects/FocusArduino":{"id":"Examples/EEGProjects/FocusArduino","title":"Send Focus Data from GUI to Arduino","description":"This tutorial shows you how to get started streaming data from the OpenBCI_GUI\'s Focus Widget via Serial connection to an Arduino UNO Rev3.","sidebar":"docs"},"Examples/EEGProjects/MotorImagery":{"id":"Examples/EEGProjects/MotorImagery","title":"Motor Imagery","description":"This tutorial was made by Rakesh C Jakati.","sidebar":"docs"},"Examples/EMGProjects/EMG_Chrome_Dino_Game":{"id":"Examples/EMGProjects/EMG_Chrome_Dino_Game","title":"EMG Chrome Dino Game","description":"In this tutorial we will show you how to play the Google Chrome Dinosaur Game without touching your laptop. To do that, we will read EMG data from your arm muscles and find the peaks which correspond to flexing, using them to trigger a jump of the dinosaur.","sidebar":"docs"},"Examples/EMGProjects/EMG_LED":{"id":"Examples/EMGProjects/EMG_LED","title":"EMG-controlled LED","description":"This tutorial is little more involved than the other EMG tutorials. No fear, we\'ve documented every step below. Happy bio-hacking!","sidebar":"docs"},"Examples/EMGProjects/EMG_Tetris":{"id":"Examples/EMGProjects/EMG_Tetris","title":"EMG-controlled Tetris","description":"In this tutorial, we will show you how to make your own muscle-controlled Tetris game. You can now play Tetris on your computer without pressing any keys!","sidebar":"docs"},"Examples/EMGProjects/EMGmusic":{"id":"Examples/EMGProjects/EMGmusic","title":"EMG-controlled Music","description":"In this tutorial, we will show you how to pause and unpause your music without pressing any keys on your laptop keyboard. To do that, we will read the peaks in EMG signals your arm muscles produce when you flex them and use them as a trigger for pausing the music played via Youtube through your computer. Feel free to connect your laptop to a Bluetooth speaker to make the music louder!","sidebar":"docs"},"Examples/EMGProjects/EMGpiano":{"id":"Examples/EMGProjects/EMGpiano","title":"EMG-controlled Piano","description":"In this tutorial, we will show you how to play the piano using just the EMG signals from your fingers! To do that, we will read EMG data from the muscles joining your fingers to your arms and find the peaks which correspond to pressing a key on a piano, using them as a trigger to play a virtual keyboard.","sidebar":"docs"},"Examples/EMGProjects/EMGscrolling":{"id":"Examples/EMGProjects/EMGscrolling","title":"EMG Scrolling","description":"In this tutorial, we will show you how to scroll up and down on your computer screen without touching the keyboard. For that, we will read the peaks in EMG signals your arm muscles produce when you flex them and use them to scroll.","sidebar":"docs"},"Examples/EMGProjects/EMGslideshow":{"id":"Examples/EMGProjects/EMGslideshow","title":"EMG-controlled Slideshow","description":"In this tutorial, we will show you how to scroll through a presentation using your eyes. To do that, we will read EMG data from the muscles around your eyes and find the peaks which correspond to blinking, using them as a trigger to scroll to the next slide. Even though we are using eye blinks in this example, any EMG signals such as those produced by your jaw when you clench it or your arms when you move them can be used.","sidebar":"docs"},"Examples/ExamplesLanding":{"id":"Examples/ExamplesLanding","title":"Example Projects","description":"The Examples directory to the left contains example projects contributed by members of the OpenBCI Community and team. For even more tutorials, head to the tutorials tag in the Community Page!","sidebar":"docs"},"Examples/VideoExperiment":{"id":"Examples/VideoExperiment","title":"Puppies and Kittens Experiment","description":"Welcome to the OpenBCI Puppies and Kittens Experiment designed by Fan Li.","sidebar":"docs"},"FAQ/Conduct":{"id":"FAQ/Conduct","title":"Code of Conduct","description":"Our Pledge","sidebar":"docs"},"FAQ/Cookie":{"id":"FAQ/Cookie","title":"OpenBCI Cookie Policy","description":"What Are Cookies","sidebar":"docs"},"FAQ/DocsUpdate":{"id":"FAQ/DocsUpdate","title":"Docs Website Update","description":"We have recently updated the Docs website! You may be seeing this page if you have attempted to access a page that has moved. You can find the same information using either the dropdowns on the left or the \\"Search Docs\\" function in the top right of this window. Enjoy!","sidebar":"docs"},"FAQ/FAQLanding":{"id":"FAQ/FAQLanding","title":"Frequently Asked Questions","description":"Welcome to our Frequently Asked Questions (FAQ)! Select the appropriate question category to proceed:","sidebar":"docs"},"FAQ/GenFAQ":{"id":"FAQ/GenFAQ","title":"General Frequently Asked Questions","description":"What does OpenBCI stand for?","sidebar":"docs"},"FAQ/HardFAQ":{"id":"FAQ/HardFAQ","title":"Hardware & Software","description":"What do I need to get started?","sidebar":"docs"},"FAQ/HowProductsGoTogether":{"id":"FAQ/HowProductsGoTogether","title":"How OpenBCI products go together?","description":"image","sidebar":"docs"},"FAQ/Liability":{"id":"FAQ/Liability","title":"Liability Policy","description":"Disclaimer of medical, clinical, or diagnostic use","sidebar":"docs"},"FAQ/PaymentFAQ":{"id":"FAQ/PaymentFAQ","title":"Purchases & Payment Processing","description":"Please note all orders ship after full payment. Orders cannot be split between multiple shipments. To make a change to your order, please email support@openbci.com ASAP. We cannot guarantee that we can satisfy the request, but we will do our best if contacted in a timely fashion.","sidebar":"docs"},"FAQ/Privacy":{"id":"FAQ/Privacy","title":"Privacy & Security","description":"Effective June 26, 2018","sidebar":"docs"},"FAQ/Returns":{"id":"FAQ/Returns","title":"RETURNS & REFUNDS","description":"Returns","sidebar":"docs"},"FAQ/ShippingFAQ":{"id":"FAQ/ShippingFAQ","title":"Shipping & Taxes","description":"Where do you ship to?","sidebar":"docs"},"ForDevelopers/FirmwareDevelopment":{"id":"ForDevelopers/FirmwareDevelopment","title":"Firmware Development","description":"Welcome all Firmware Developers! In this document, you can find a list of firmware resources for current boards. This is a great starting point if you are interested in how a board works at the firmware level or an expert user interested in modifying the firmware.","sidebar":"docs"},"ForDevelopers/ForDevelopersLanding":{"id":"ForDevelopers/ForDevelopersLanding","title":"For Developers","description":"The information in this directory will help you start developing with OpenBCI technology.","sidebar":"docs"},"ForDevelopers/HardwareDevelopment":{"id":"ForDevelopers/HardwareDevelopment","title":"Hardware Development","description":"Welcome all Hardware Developers! Are you interested in how an OpenBCI board is made? Do you want to make one yourself or incorporate one into a project? This is the place for you! Here you will find resources, including full schematics, for current and past hardware.","sidebar":"docs"},"ForDevelopers/SoftwareDevelopment":{"id":"ForDevelopers/SoftwareDevelopment","title":"Software Development","description":"Welcome all Software Developers! In this document, we will go over the tools available to assist in integrating OpenBCI hardware with projects in multiple programming languages. Also, we will briefly look at how OpenBCI hardware is integrated into the OpenBCI GUI using Processing).","sidebar":"docs"},"Ganglion/GanglionDataFormat":{"id":"Ganglion/GanglionDataFormat","title":"Ganglion Data Format","description":"This discussion of the OpenBCI data format only applies to the OpenBCI Ganglion. The Ganglion contains a Simblee microcontroller that can both be programmed through the Arduino IDE or over-the-air (OTA). The Simblee has an on-board radio module. The format of the Ganglion data as seen on the PC is defined by a combination of the Arduino code on the Ganglion board and software on your computer. So, if you don\'t like the data format defined here, feel free to change it! In general, and believe us, we tried, you can\'t send more then 100 BLE packets per second. For more info on the byte stream parsing on the computer side, or for a working example, see the NodeJS Ganglion Driver.","sidebar":"docs"},"Ganglion/GanglionLanding":{"id":"Ganglion/GanglionLanding","title":"Ganglion Board","description":"Buy it!","sidebar":"docs"},"Ganglion/GanglionProgram":{"id":"Ganglion/GanglionProgram","title":"Ganglion Programming Tutorial","description":"Please note, you do NOT need to program the Ganglion in order to use it. All OpenBCI boards ship ready to use out of the box. This guide is for users who want to upload their own firmware to the Ganglion or modify existing firmware.","sidebar":"docs"},"Ganglion/GanglionSDK":{"id":"Ganglion/GanglionSDK","title":"Ganglion SDK","description":"The OpenBCI boards communicate using a byte string (mostly ASCII) command protocol. This Doc covers command use for the OpenBCI Ganglion. Further this Doc covers the commands needed in order to alter the radio system. There have been several iterations of the firmware. Please send reset commands to your board to see what firmware you have if you\'re unsure.","sidebar":"docs"},"Ganglion/GanglionSpecs":{"id":"Ganglion/GanglionSpecs","title":"Ganglion Specs","description":"BUY IT!","sidebar":"docs"},"GettingStarted/Biosensing-Setups/ECGSetup":{"id":"GettingStarted/Biosensing-Setups/ECGSetup","title":"Setting up for ECG","description":"This document will show you how to read ECG data (electrical signals from the heart) using OpenBCI hardware and GUI.","sidebar":"docs"},"GettingStarted/Biosensing-Setups/EEGSetup":{"id":"GettingStarted/Biosensing-Setups/EEGSetup","title":"Setting up for EEG","description":"This page will explain the most basic setup to process EEG Data using your OpenBCI board, using our gold cup electrodes.","sidebar":"docs"},"GettingStarted/Biosensing-Setups/EMGSetup":{"id":"GettingStarted/Biosensing-Setups/EMGSetup","title":"Setting up for EMG","description":"This document will show you how to read EMG data (electrical signals from muscles) using OpenBCI hardware and GUI.","sidebar":"docs"},"GettingStarted/Biosensing-Setups/ExGSetup":{"id":"GettingStarted/Biosensing-Setups/ExGSetup","title":"Setting up for EEG, EMG, and ECG at the same time","description":"OpenBCI Cyton+Daisy board offers a wide range of flexibility with more signal channels.","sidebar":"docs"},"GettingStarted/Boards/CytonGS":{"id":"GettingStarted/Boards/CytonGS","title":"Cyton Getting Started Guide","description":"This guide will walk you through setting up your computer to use the Cyton and USB Dongle, using the OpenBCI_GUI Application, and how to get EEG/EMG/EKG from your own body! Please review this guide in its entirety before starting and consult the Cyton Biosensing Tutorial Video for extra guidance. Have fun!","sidebar":"docs"},"GettingStarted/Boards/DaisyGS":{"id":"GettingStarted/Boards/DaisyGS","title":"Daisy Getting Started Guide","description":"This guide will walk you through getting 16-channel input on your Cyton+Daisy Module","sidebar":"docs"},"GettingStarted/Boards/GanglionGS":{"id":"GettingStarted/Boards/GanglionGS","title":"Ganglion Getting Started Guide","description":"Overview","sidebar":"docs"},"GettingStarted/Boards/WiFiGS":{"id":"GettingStarted/Boards/WiFiGS","title":"WiFi Shield Getting Started Guide","description":"Overview","sidebar":"docs"},"GettingStarted/Community/Community":{"id":"GettingStarted/Community/Community","title":"Welcome to the OpenBCI Community","description":"openbci.com/community/","sidebar":"docs"},"GettingStarted/Documentation/DocEdits":{"id":"GettingStarted/Documentation/DocEdits","title":"Editing Docs Guide","description":"This page will explain the process of contributing to the OpenBCI documentation.","sidebar":"docs"},"GettingStarted/GettingStartedLanding":{"id":"GettingStarted/GettingStartedLanding","title":"Getting Started","description":"This directory will show you everything you need to know to get started with OpenBCI.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/BioEra":{"id":"Software/CompatibleThirdPartySoftware/BioEra","title":"BioEra","description":"From the BioEra homepage: BioEra is a visual designer useful for analyzing signals in real time. It can be used with any device with ability to stream data to a computer.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/BrainBay":{"id":"Software/CompatibleThirdPartySoftware/BrainBay","title":"BrainBay","description":"From their OpenBCI tutorials page: BrainBay is an open-source visual programming language (VPL) for rapid prototyping of EEG digital signal processing steps (or data flows.)","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/LSL":{"id":"Software/CompatibleThirdPartySoftware/LSL","title":"Lab Streaming Layer (LSL)","description":"Lab streaming layer is a system for synchronizing streaming data for live analysis or recording. LSL is a good way to send your OpenBCI stream to applications that can record or manipulate the data, such as Matlab (see our Matlab tutorial for using LSL in this context).","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/Matlab":{"id":"Software/CompatibleThirdPartySoftware/Matlab","title":"MATLAB","description":"MATLAB is a powerful numerical computing language and environment that is widely used in a wide variety of academic, research, and industrial applications.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/Neuromore":{"id":"Software/CompatibleThirdPartySoftware/Neuromore","title":"Neuromore","description":"Neuromore is an EEG streaming and processing studio. Like BrainBay and BioEra, it provides a visual designer that can be used to process signals real-time.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/OpenVibe":{"id":"Software/CompatibleThirdPartySoftware/OpenVibe","title":"OpenViBE","description":"Overview","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/VirtualBox":{"id":"Software/CompatibleThirdPartySoftware/VirtualBox","title":"VirtualBox Windows Guide","description":"Some of the software compatible with OpenBCI products requires a Windows operating system. If you have a non-windows computer, you can still use this software through a Windows virtual machine on VirtualBox.","sidebar":"docs"},"Software/OpenBCISoftware/GUIDocs":{"id":"Software/OpenBCISoftware/GUIDocs","title":"The OpenBCI GUI","description":"image","sidebar":"docs"},"Software/OpenBCISoftware/GUIWidgets":{"id":"Software/OpenBCISoftware/GUIWidgets","title":"GUI Widget Guide","description":"What is a GUI Widget?","sidebar":"docs"},"Software/OpenBCISoftware/NeuroFly_Toolkit":{"id":"Software/OpenBCISoftware/NeuroFly_Toolkit","title":"NeuroFly Toolkit","description":"This tutorial will show you how to control a joystick using EMG data with the OpenBCI GUI. You can then use this customizable, muscle-activated joystick for any purpose of your choosing! OpenBCI used this to control a drone in the 2023 OpenBCI TED Talk.","sidebar":"docs"},"Software/SoftwareLanding":{"id":"Software/SoftwareLanding","title":"Compatible Software","description":"OpenBCI Software","sidebar":"docs"},"ThirdParty/EmotiBit/EmotiBit_Guide":{"id":"ThirdParty/EmotiBit/EmotiBit_Guide","title":"EmotiBit Guide","description":"Overview","sidebar":"docs"},"ThirdParty/IDUN_Dryode/Dryode":{"id":"ThirdParty/IDUN_Dryode/Dryode","title":"IDUN Dryode","description":"Overview","sidebar":"docs"},"ThirdParty/Myoware/MyoWareCyton":{"id":"ThirdParty/Myoware/MyoWareCyton","title":"MyoWare OpenBCI Integration (Cyton Board)","description":"The Myoware 2.0 board cannot be used with the Ganglion board. If you have purchased a Myoware 2.0 board with the intention of using it with the Ganglion board, please contact Customer support at contact@openbci.com","sidebar":"docs"},"ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing":{"id":"ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing","title":"Pulse Sensor Guide","description":"The Pulse Sensor can be connected to the Cyton or any Arduino board to easily obtain your heart rate using photoplethysmogram (PPG).","sidebar":"docs"},"ThirdParty/ThinkPulse/ThinkPulse":{"id":"ThirdParty/ThinkPulse/ThinkPulse","title":"ThinkPulse Getting Started Guide","description":"Available exclusively worldwide only on the OpenBCI\xae store.","sidebar":"docs"},"ThirdParty/ThirdPartyLanding":{"id":"ThirdParty/ThirdPartyLanding","title":"Third-Party Hardware","description":"The directory to the left contains documents to explain the integration between OpenBCI and compatible third-party hardware. This landing page summarizes the variety of sampling modalities!","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiAPI":{"id":"ThirdParty/WiFiShield/WiFiAPI","title":"OpenBCI WiFi Shield API","description":"The OpenBCI Wifi Shield seeks to offer a plug and play Wifi solution for the OpenBCI Cyton and Ganglion.","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiLanding":{"id":"ThirdParty/WiFiShield/WiFiLanding","title":"OpenBCI WiFi","description":"BUY IT!","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiProgam":{"id":"ThirdParty/WiFiShield/WiFiProgam","title":"Wifi Shield Programming Tutorial","description":"Overview","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiSDK":{"id":"ThirdParty/WiFiShield/WiFiSDK","title":"OpenBCI Wifi SDK","description":"The purpose of this doc is to describe what\'s required to interface another micro-controller with the WiFi Shield.","sidebar":"docs"},"Troubleshooting/FTDI_Fix_Linux":{"id":"Troubleshooting/FTDI_Fix_Linux","title":"FTDI Buffer Fix on Linux","description":"Summary","sidebar":"docs"},"Troubleshooting/FTDI_Fix_Mac":{"id":"Troubleshooting/FTDI_Fix_Mac","title":"FTDI Buffer Fix on OS X","description":"Summary","sidebar":"docs"},"Troubleshooting/FTDI_Fix_Windows":{"id":"Troubleshooting/FTDI_Fix_Windows","title":"FTDI Buffer Fix on Windows","description":"Tested on:","sidebar":"docs"},"Troubleshooting/GUI_Troubleshooting":{"id":"Troubleshooting/GUI_Troubleshooting","title":"GUI Troubleshooting","description":"The GUI Console Log","sidebar":"docs"},"Troubleshooting/MacOSGanglionBLEWorkaround":{"id":"Troubleshooting/MacOSGanglionBLEWorkaround","title":"MacOS Ganglion BLE Workaround","description":"In later versions of MacOS (generally MacOS 11+) there is an issue where Bluetooth permissions are not requested by the application. This prevents the embedded native BLE library from accessing the Bluetooth adapter and therefore Ganglion boards (and other Bluetooth devices) cannot be found. This issue appears to be related to application hardening requirements introduced in MacOS 10.14.5. Most importantly, the JDK 8 version that ships with Processing 3.5.4 and earlier is not notarized and therefore cannot request permissions from the OS.","sidebar":"docs"},"Troubleshooting/minimizingNoise":{"id":"Troubleshooting/minimizingNoise","title":"Minimizing Noise","description":"Are you getting \\"noisy\\" data from your device? There are several possible reasons for this. Let\'s go through some simple troubleshooting steps that resolve most issues.","sidebar":"docs"},"Troubleshooting/TroubleshootingLanding":{"id":"Troubleshooting/TroubleshootingLanding","title":"Troubleshooting Landing","description":"The guides below offer tips on common hardware and software issues and how to fix them.","sidebar":"docs"},"Welcome":{"id":"Welcome","title":"Welcome to the OpenBCI Community","description":"Welcome to the OpenBCI Learning Pages! Here you will find a wide range of guides and tutorials that are intended to teach you how to use your OpenBCI gear. If you run into issues or have additional questions, head to our Forum with daily active users. Check out the Community Page for project ideas!","sidebar":"docs"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.edd0b0ec.js b/assets/js/935f2afb.edd0b0ec.js deleted file mode 100644 index d47f1aa98..000000000 --- a/assets/js/935f2afb.edd0b0ec.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk=self.webpackChunk||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"docs":[{"type":"category","collapsed":true,"collapsible":true,"label":"Welcome to OpenBCI","items":[{"type":"link","label":"Welcome to the OpenBCI Community","href":"/","docId":"Welcome"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Getting Started","items":[{"type":"link","label":"Getting Started","href":"/GettingStarted/GettingStartedLanding","docId":"GettingStarted/GettingStartedLanding"},{"type":"category","label":"Boards","items":[{"type":"link","label":"Cyton Getting Started Guide","href":"/GettingStarted/Boards/CytonGS","docId":"GettingStarted/Boards/CytonGS"},{"type":"link","label":"Daisy Getting Started Guide","href":"/GettingStarted/Boards/DaisyGS","docId":"GettingStarted/Boards/DaisyGS"},{"type":"link","label":"Ganglion Getting Started Guide","href":"/GettingStarted/Boards/GanglionGS","docId":"GettingStarted/Boards/GanglionGS"},{"type":"link","label":"WiFi Shield Getting Started Guide","href":"/GettingStarted/Boards/WiFiGS","docId":"GettingStarted/Boards/WiFiGS"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Biosensing Setups","items":[{"type":"link","label":"Setting up for EEG","href":"/GettingStarted/Biosensing-Setups/EEGSetup","docId":"GettingStarted/Biosensing-Setups/EEGSetup"},{"type":"link","label":"Setting up for ECG","href":"/GettingStarted/Biosensing-Setups/ECGSetup","docId":"GettingStarted/Biosensing-Setups/ECGSetup"},{"type":"link","label":"Setting up for EMG","href":"/GettingStarted/Biosensing-Setups/EMGSetup","docId":"GettingStarted/Biosensing-Setups/EMGSetup"},{"type":"link","label":"Setting up for EEG, EMG, and ECG at the same time","href":"/GettingStarted/Biosensing-Setups/ExGSetup","docId":"GettingStarted/Biosensing-Setups/ExGSetup"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Community","items":[{"type":"link","label":"Welcome to the OpenBCI Community","href":"/GettingStarted/Community/Community","docId":"GettingStarted/Community/Community"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Documentation","items":[{"type":"link","label":"Editing Docs Guide","href":"/GettingStarted/Documentation/DocEdits","docId":"GettingStarted/Documentation/DocEdits"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Cyton Board","items":[{"type":"link","label":"Cyton Board","href":"/Cyton/CytonLanding","docId":"Cyton/CytonLanding"},{"type":"link","label":"Cyton Specs","href":"/Cyton/CytonSpecs","docId":"Cyton/CytonSpecs"},{"type":"link","label":"Cyton Data Format","href":"/Cyton/CytonDataFormat","docId":"Cyton/CytonDataFormat"},{"type":"link","label":"Cyton Board SDK","href":"/Cyton/CytonSDK","docId":"Cyton/CytonSDK"},{"type":"link","label":"Cyton Board Programming Tutorial","href":"/Cyton/CytonProgram","docId":"Cyton/CytonProgram"},{"type":"link","label":"Cyton Radios Programming Tutorial","href":"/Cyton/CytonRadios","docId":"Cyton/CytonRadios"},{"type":"link","label":"External Trigger on OpenBCI Cyton Board","href":"/Cyton/CytonExternal","docId":"Cyton/CytonExternal"},{"type":"link","label":"Using SD Card with Cyton and CytonDaisy Board","href":"/Cyton/CytonSDCard","docId":"Cyton/CytonSDCard"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Ganglion Board","items":[{"type":"link","label":"Ganglion Board","href":"/Ganglion/GanglionLanding","docId":"Ganglion/GanglionLanding"},{"type":"link","label":"Ganglion Specs","href":"/Ganglion/GanglionSpecs","docId":"Ganglion/GanglionSpecs"},{"type":"link","label":"Ganglion Data Format","href":"/Ganglion/GanglionDataFormat","docId":"Ganglion/GanglionDataFormat"},{"type":"link","label":"Ganglion SDK","href":"/Ganglion/GanglionSDK","docId":"Ganglion/GanglionSDK"},{"type":"link","label":"Ganglion Programming Tutorial","href":"/Ganglion/GanglionProgram","docId":"Ganglion/GanglionProgram"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Headwear & Electrodes","items":[{"type":"link","label":"Add Ons","href":"/AddOns/AddOnLanding","docId":"AddOns/AddOnLanding"},{"type":"category","label":"Headwear","items":[{"type":"link","label":"Ultracortex Mark IV","href":"/AddOns/Headwear/MarkIV","docId":"AddOns/Headwear/MarkIV"},{"type":"link","label":"OpenBCI EEG Headband Kit Guide","href":"/AddOns/Headwear/HeadBand","docId":"AddOns/Headwear/HeadBand"},{"type":"link","label":"Electrode Cap Getting Started Guide","href":"/AddOns/Headwear/ElectrodeCap","docId":"AddOns/Headwear/ElectrodeCap"},{"type":"link","label":"Gelfree Electrode Cap Guide","href":"/AddOns/Headwear/GelfreeElectrodeCap","docId":"AddOns/Headwear/GelfreeElectrodeCap"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Electrodes","items":[{"type":"link","label":"Electrode Guide","href":"/AddOns/Electrodes/ElectrodesLanding","docId":"AddOns/Electrodes/ElectrodesLanding"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Third-Party Hardware","items":[{"type":"link","label":"Third-Party Hardware","href":"/ThirdParty/ThirdPartyLanding","docId":"ThirdParty/ThirdPartyLanding"},{"type":"category","label":"EmotiBit","items":[{"type":"link","label":"EmotiBit Guide","href":"/ThirdParty/EmotiBit/EmotiBit_Guide","docId":"ThirdParty/EmotiBit/EmotiBit_Guide"}],"collapsible":true,"collapsed":true},{"type":"category","label":"IDUN Dryode","items":[{"type":"link","label":"IDUN Dryode","href":"/ThirdParty/IDUN_Dryode/Dryode","docId":"ThirdParty/IDUN_Dryode/Dryode"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Myoware","items":[{"type":"link","label":"MyoWare OpenBCI Integration (Cyton Board)","href":"/ThirdParty/Myoware/MyoWareCyton","docId":"ThirdParty/Myoware/MyoWareCyton"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Pulse Sensor","items":[{"type":"link","label":"Pulse Sensor Guide","href":"/ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing","docId":"ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing"}],"collapsible":true,"collapsed":true},{"type":"category","label":"ThinkPulse","items":[{"type":"link","label":"ThinkPulse Getting Started Guide","href":"/ThirdParty/ThinkPulse/ThinkPulse","docId":"ThirdParty/ThinkPulse/ThinkPulse"}],"collapsible":true,"collapsed":true},{"type":"category","label":"WiFi Shield","items":[{"type":"link","label":"OpenBCI WiFi","href":"/ThirdParty/WiFiShield/WiFiLanding","docId":"ThirdParty/WiFiShield/WiFiLanding"},{"type":"link","label":"Wifi Shield Programming Tutorial","href":"/ThirdParty/WiFiShield/WiFiProgam","docId":"ThirdParty/WiFiShield/WiFiProgam"},{"type":"link","label":"OpenBCI WiFi Shield API","href":"/ThirdParty/WiFiShield/WiFiAPI","docId":"ThirdParty/WiFiShield/WiFiAPI"},{"type":"link","label":"OpenBCI Wifi SDK","href":"/ThirdParty/WiFiShield/WiFiSDK","docId":"ThirdParty/WiFiShield/WiFiSDK"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Software","items":[{"type":"link","label":"Compatible Software","href":"/Software/SoftwareLanding","docId":"Software/SoftwareLanding"},{"type":"category","label":"Developed By OpenBCI","items":[{"type":"link","label":"The OpenBCI GUI","href":"/Software/OpenBCISoftware/GUIDocs","docId":"Software/OpenBCISoftware/GUIDocs"},{"type":"link","label":"GUI Widget Guide","href":"/Software/OpenBCISoftware/GUIWidgets","docId":"Software/OpenBCISoftware/GUIWidgets"},{"type":"link","label":"NeuroFly Toolkit","href":"/Software/OpenBCISoftware/NeuroFly_Toolkit","docId":"Software/OpenBCISoftware/NeuroFly_Toolkit"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Compatible Third Party Software","items":[{"type":"link","label":"MATLAB","href":"/Software/CompatibleThirdPartySoftware/Matlab","docId":"Software/CompatibleThirdPartySoftware/Matlab"},{"type":"link","label":"Neuromore","href":"/Software/CompatibleThirdPartySoftware/Neuromore","docId":"Software/CompatibleThirdPartySoftware/Neuromore"},{"type":"link","label":"OpenViBE","href":"/Software/CompatibleThirdPartySoftware/OpenVibe","docId":"Software/CompatibleThirdPartySoftware/OpenVibe"},{"type":"link","label":"Lab Streaming Layer (LSL)","href":"/Software/CompatibleThirdPartySoftware/LSL","docId":"Software/CompatibleThirdPartySoftware/LSL"},{"type":"link","label":"BrainBay","href":"/Software/CompatibleThirdPartySoftware/BrainBay","docId":"Software/CompatibleThirdPartySoftware/BrainBay"},{"type":"link","label":"BioEra","href":"/Software/CompatibleThirdPartySoftware/BioEra","docId":"Software/CompatibleThirdPartySoftware/BioEra"},{"type":"link","label":"VirtualBox Windows Guide","href":"/Software/CompatibleThirdPartySoftware/VirtualBox","docId":"Software/CompatibleThirdPartySoftware/VirtualBox"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"For Developers","items":[{"type":"link","label":"For Developers","href":"/ForDevelopers/ForDevelopersLanding","docId":"ForDevelopers/ForDevelopersLanding"},{"type":"link","label":"Software Development","href":"/ForDevelopers/SoftwareDevelopment","docId":"ForDevelopers/SoftwareDevelopment"},{"type":"link","label":"Firmware Development","href":"/ForDevelopers/FirmwareDevelopment","docId":"ForDevelopers/FirmwareDevelopment"},{"type":"link","label":"Hardware Development","href":"/ForDevelopers/HardwareDevelopment","docId":"ForDevelopers/HardwareDevelopment"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Deprecated Documents","items":[{"type":"link","label":"Deprecated Docs","href":"/Deprecated/DeprecatedLanding","docId":"Deprecated/DeprecatedLanding"},{"type":"link","label":"Spiderclaw V1 & V2 (deprecated)","href":"/Deprecated/SpiderclawDep","docId":"Deprecated/SpiderclawDep"},{"type":"link","label":"OpenBCI 8bit Board (no longer in production)","href":"/Deprecated/8bitBoardDep","docId":"Deprecated/8bitBoardDep"},{"type":"link","label":"Ultracortex Mark 1","href":"/Deprecated/UltracortexMark1Dep","docId":"Deprecated/UltracortexMark1Dep"},{"type":"link","label":"Ultracortex Mark 2","href":"/Deprecated/UltracortexMark2Dep","docId":"Deprecated/UltracortexMark2Dep"},{"type":"link","label":"Ultracortex Mark 2","href":"/Deprecated/UltracortexMark2Dep","docId":"Deprecated/UltracortexMark2Dep"},{"type":"link","label":"Ultracortex Mark III Nova and Supernova","href":"/Deprecated/UltracortexMark3_NovaDep","docId":"Deprecated/UltracortexMark3_NovaDep"},{"type":"link","label":"Ultracortex Mark III","href":"/Deprecated/MarkIII","docId":"Deprecated/MarkIII"},{"type":"link","label":"Python and OpenBCI","href":"/Deprecated/Python","docId":"Deprecated/Python"},{"type":"link","label":"OpenBCI Hub","href":"/Deprecated/Hub","docId":"Deprecated/Hub"},{"type":"link","label":"MyoWare OpenBCI Integration (Cyton Board)","href":"/Deprecated/MyoCyton","docId":"Deprecated/MyoCyton"},{"type":"link","label":"MyoWare OpenBCI Integration (Ganglion Board)","href":"/Deprecated/MyoGanglion","docId":"Deprecated/MyoGanglion"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Troubleshooting","items":[{"type":"link","label":"Troubleshooting Landing","href":"/Troubleshooting/TroubleshootingLanding","docId":"Troubleshooting/TroubleshootingLanding"},{"type":"link","label":"Minimizing Noise","href":"/Troubleshooting/minimizingNoise","docId":"Troubleshooting/minimizingNoise"},{"type":"link","label":"GUI Troubleshooting","href":"/Troubleshooting/GUI_Troubleshooting","docId":"Troubleshooting/GUI_Troubleshooting"},{"type":"link","label":"FTDI Buffer Fix on Linux","href":"/Troubleshooting/FTDI_Fix_Linux","docId":"Troubleshooting/FTDI_Fix_Linux"},{"type":"link","label":"FTDI Buffer Fix on OS X","href":"/Troubleshooting/FTDI_Fix_Mac","docId":"Troubleshooting/FTDI_Fix_Mac"},{"type":"link","label":"FTDI Buffer Fix on Windows","href":"/Troubleshooting/FTDI_Fix_Windows","docId":"Troubleshooting/FTDI_Fix_Windows"},{"type":"link","label":"MacOS Ganglion BLE Workaround","href":"/Troubleshooting/MacOSGanglionBLEWorkaround","docId":"Troubleshooting/MacOSGanglionBLEWorkaround"}]},{"type":"category","collapsed":true,"collapsible":true,"label":"Example Projects","items":[{"type":"link","label":"Example Projects","href":"/Examples/ExamplesLanding","docId":"Examples/ExamplesLanding"},{"type":"category","label":"Experiments","items":[{"type":"link","label":"Puppies and Kittens Experiment","href":"/Examples/VideoExperiment","docId":"Examples/VideoExperiment"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Community Page Projects","items":[{"type":"link","label":"Community Page Projects","href":"/Examples/CommunityPageProjects","docId":"Examples/CommunityPageProjects"}],"collapsible":true,"collapsed":true},{"type":"category","label":"EMG Projects and Tutorials","items":[{"type":"link","label":"EMG Scrolling","href":"/Examples/EMGProjects/EMGscrolling","docId":"Examples/EMGProjects/EMGscrolling"},{"type":"link","label":"EMG-controlled Music","href":"/Examples/EMGProjects/EMGmusic","docId":"Examples/EMGProjects/EMGmusic"},{"type":"link","label":"EMG-controlled Slideshow","href":"/Examples/EMGProjects/EMGslideshow","docId":"Examples/EMGProjects/EMGslideshow"},{"type":"link","label":"EMG-controlled LED","href":"/Examples/EMGProjects/EMG_LED","docId":"Examples/EMGProjects/EMG_LED"},{"type":"link","label":"EMG Chrome Dino Game","href":"/Examples/EMGProjects/EMG_Chrome_Dino_Game","docId":"Examples/EMGProjects/EMG_Chrome_Dino_Game"},{"type":"link","label":"EMG-controlled Tetris","href":"/Examples/EMGProjects/EMG_Tetris","docId":"Examples/EMGProjects/EMG_Tetris"},{"type":"link","label":"EMG-controlled Piano","href":"/Examples/EMGProjects/EMGpiano","docId":"Examples/EMGProjects/EMGpiano"}],"collapsible":true,"collapsed":true},{"type":"category","label":"EEG Projects and Tutorials","items":[{"type":"link","label":"Send Focus Data from GUI to Arduino","href":"/Examples/EEGProjects/FocusArduino","docId":"Examples/EEGProjects/FocusArduino"},{"type":"link","label":"Motor Imagery","href":"/Examples/EEGProjects/MotorImagery","docId":"Examples/EEGProjects/MotorImagery"}],"collapsible":true,"collapsed":true}]},{"type":"category","collapsed":true,"collapsible":true,"label":"FAQ","items":[{"type":"category","label":"FAQ","items":[{"type":"link","label":"Frequently Asked Questions","href":"/FAQ/FAQLanding","docId":"FAQ/FAQLanding"},{"type":"link","label":"General Frequently Asked Questions","href":"/FAQ/GenFAQ","docId":"FAQ/GenFAQ"},{"type":"link","label":"How OpenBCI products go together?","href":"/FAQ/HowProductsGoTogether","docId":"FAQ/HowProductsGoTogether"},{"type":"link","label":"Hardware & Software","href":"/FAQ/HardFAQ","docId":"FAQ/HardFAQ"},{"type":"link","label":"Purchases & Payment Processing","href":"/FAQ/PaymentFAQ","docId":"FAQ/PaymentFAQ"},{"type":"link","label":"Shipping & Taxes","href":"/FAQ/ShippingFAQ","docId":"FAQ/ShippingFAQ"},{"type":"link","label":"Docs Website Update","href":"/FAQ/DocsUpdate","docId":"FAQ/DocsUpdate"}],"collapsible":true,"collapsed":true},{"type":"category","label":"Policies","items":[{"type":"link","label":"OpenBCI Cookie Policy","href":"/FAQ/Cookie","docId":"FAQ/Cookie"},{"type":"link","label":"Privacy & Security","href":"/FAQ/Privacy","docId":"FAQ/Privacy"},{"type":"link","label":"RETURNS & REFUNDS","href":"/FAQ/Returns","docId":"FAQ/Returns"},{"type":"link","label":"Liability Policy","href":"/FAQ/Liability","docId":"FAQ/Liability"}],"collapsible":true,"collapsed":true}]}]},"docs":{"AddOns/AddOnLanding":{"id":"AddOns/AddOnLanding","title":"Add Ons","description":"This section summarizes the headwear and electrodes that goes with OpenBCI boards to help gather data.","sidebar":"docs"},"AddOns/Electrodes/ElectrodesLanding":{"id":"AddOns/Electrodes/ElectrodesLanding","title":"Electrode Guide","description":"OpenBCI Boards are compatible with a variety of different electrodes.","sidebar":"docs"},"AddOns/Headwear/ElectrodeCap":{"id":"AddOns/Headwear/ElectrodeCap","title":"Electrode Cap Getting Started Guide","description":"This is a guide to setting up and cleaning your OpenBCI Electrode Cap. Please consult the Electrode Cap","sidebar":"docs"},"AddOns/Headwear/GelfreeElectrodeCap":{"id":"AddOns/Headwear/GelfreeElectrodeCap","title":"Gelfree Electrode Cap Guide","description":"This is a guide to setting up and cleaning your OpenBCI Gelfree Electrode Cap. Please consult the Gelfree Electrode Cap","sidebar":"docs"},"AddOns/Headwear/HeadBand":{"id":"AddOns/Headwear/HeadBand","title":"OpenBCI EEG Headband Kit Guide","description":"Now available in our shop!","sidebar":"docs"},"AddOns/Headwear/MarkIV":{"id":"AddOns/Headwear/MarkIV","title":"Ultracortex Mark IV","description":"Development Period: January 2016 Through the Present","sidebar":"docs"},"Cyton/CytonDataFormat":{"id":"Cyton/CytonDataFormat","title":"Cyton Data Format","description":"This discussion of the OpenBCI data format only applies to OpenBCI v1 (2014-2016) and v2.0.0 (Fall 2016). For OpenBCI Cyton, the OpenBCI board contains either a ChipKIT or ATmega microcontroller that can both be programmed through the Arduino IDE. The Cyton board has an on-board RFDuino radio module acting as a \\"Device\\". The Cyton system includes a USB dongle for the PC, which acts as the RFDuino \\"Host\\". The format of the OpenBCI data as seen on the PC is defined by a combination of the Arduino code on the Cyton board and of the RFDuino code running on the Host. So, if you don\'t like the data format defined here, feel free to change it! For more info on the v2 firmware, see these Notes On Updating and Using v2.0.0 Cyton Firmware. There is also further information on controlling the OpenBCI Cyton on our OpenBCI Cyton SDK page.","sidebar":"docs"},"Cyton/CytonExternal":{"id":"Cyton/CytonExternal","title":"External Trigger on OpenBCI Cyton Board","description":"Sometimes, when studying EEG or other biopotential signals, you will want to have precise timing between external events or stimulus and the data stream. For example, if you are working with P300 waves it is necessary to know the exact time that the signal was presented to the subject in order to look for the tell-tale brain wave that happens about 300mS after the stimulus.","sidebar":"docs"},"Cyton/CytonLanding":{"id":"Cyton/CytonLanding","title":"Cyton Board","description":"Buy it!","sidebar":"docs"},"Cyton/CytonProgram":{"id":"Cyton/CytonProgram","title":"Cyton Board Programming Tutorial","description":"Note, you do not need to do any board programming if you want to use the Cyton out-of-the-box. All OpenBCI boards ship already programmed, i.e. with firmware uploaded. Email support@openbci.com before attempting to update or alter board firmware, or if you think there is an issue with your board. DO NOT attempt to upload firmware to your board unless specifically instructed to do so.","sidebar":"docs"},"Cyton/CytonRadios":{"id":"Cyton/CytonRadios","title":"Cyton Radios Programming Tutorial","description":"Note, you do not need to do any board programming if you want to use the Cyton and Dongle out-of-the-box. All OpenBCI boards ship already programmed, i.e. with firmware uploaded. Email support@openbci.com before attempting to update or alter board firmware, or if you think there is an issue with your board. DO NOT attempt to upload firmware to your Cyton board or dongle unless specifically instructed to do so.","sidebar":"docs"},"Cyton/CytonSDCard":{"id":"Cyton/CytonSDCard","title":"Using SD Card with Cyton and CytonDaisy Board","description":"Overview","sidebar":"docs"},"Cyton/CytonSDK":{"id":"Cyton/CytonSDK","title":"Cyton Board SDK","description":"The OpenBCI Cyton boards communicate using a byte string (mostly ASCII) command protocol. This Doc covers command use for the OpenBCI Cyton and 8bit boards. Some of the commands are board specific, where noted. Further this Doc covers the commands needed in order to alter the radio system. There have been several iterations of the firmware, the 8bit board runs v0, while the Cyton runs v1 and Boards shipped as of Fall 2016 run v2.0.0. v3.0.0 will begin shipping with boards in August of 2017.","sidebar":"docs"},"Cyton/CytonSpecs":{"id":"Cyton/CytonSpecs","title":"Cyton Specs","description":"BUY IT!","sidebar":"docs"},"Deprecated/8bitBoardDep":{"id":"Deprecated/8bitBoardDep","title":"OpenBCI 8bit Board (no longer in production)","description":"8bit Board Specs:","sidebar":"docs"},"Deprecated/DeprecatedLanding":{"id":"Deprecated/DeprecatedLanding","title":"Deprecated Docs","description":"This directory houses all deprecated documentation.","sidebar":"docs"},"Deprecated/Hub":{"id":"Deprecated/Hub","title":"OpenBCI Hub","description":"THIS SOFTWARE HAS BEEN DEPRECATED AND IS NO LONGER IN ACTIVE DEVELOPMENT.","sidebar":"docs"},"Deprecated/MarkIII":{"id":"Deprecated/MarkIII","title":"Ultracortex Mark III","description":"Development Period: June 2016","sidebar":"docs"},"Deprecated/MyoCyton":{"id":"Deprecated/MyoCyton","title":"MyoWare OpenBCI Integration (Cyton Board)","description":"THIS HARDWARE VERSION HAS BEEN DEPRECATED AND IS NO LONGER IN PRODUCTION.","sidebar":"docs"},"Deprecated/MyoGanglion":{"id":"Deprecated/MyoGanglion","title":"MyoWare OpenBCI Integration (Ganglion Board)","description":"THIS HARDWARE VERSION HAS BEEN DEPRECATED AND IS NO LONGER IN PRODUCTION.","sidebar":"docs"},"Deprecated/Python":{"id":"Deprecated/Python","title":"Python and OpenBCI","description":"THIS DOCUMENT HAS BEEN DEPRECATED. PLEASE REFER TO \\"FOR DEVELOPERS\\" SECTION FOR INFORMATION ON BRAINFLOW-PYTHON.","sidebar":"docs"},"Deprecated/SpiderclawDep":{"id":"Deprecated/SpiderclawDep","title":"Spiderclaw V1 & V2 (deprecated)","description":"Check out the following blog post (recently re-posted), for a detailed guide on the V1 & V2 Spiderclaw designs, as well as links to the relevant .stl, .obj, and Autodesk Maya files for Spiderclaw V1 and V2.","sidebar":"docs"},"Deprecated/UltracortexMark1Dep":{"id":"Deprecated/UltracortexMark1Dep","title":"Ultracortex Mark 1","description":"Files related to the ultracortex, the 3D-printable EEG headset compatible with OpenBCI (currently under development).","sidebar":"docs"},"Deprecated/UltracortexMark2Dep":{"id":"Deprecated/UltracortexMark2Dep","title":"Ultracortex Mark 2","description":"image","sidebar":"docs"},"Deprecated/UltracortexMark3_NovaDep":{"id":"Deprecated/UltracortexMark3_NovaDep","title":"Ultracortex Mark III Nova and Supernova","description":"Development Period: June 2016","sidebar":"docs"},"Deprecated/UltracortexMark3Dep":{"id":"Deprecated/UltracortexMark3Dep","title":"Ultracortex Mark 3","description":"Development Period: July 2015 \u2014 September 2015"},"Examples/CommunityPageProjects":{"id":"Examples/CommunityPageProjects","title":"Community Page Projects","description":"Head over to the Community Page for project tutorials contributed by OpenBCI Community members! Use the \\"tutorials\\" tag to filter.","sidebar":"docs"},"Examples/EEGProjects/FocusArduino":{"id":"Examples/EEGProjects/FocusArduino","title":"Send Focus Data from GUI to Arduino","description":"This tutorial shows you how to get started streaming data from the OpenBCI_GUI\'s Focus Widget via Serial connection to an Arduino UNO Rev3.","sidebar":"docs"},"Examples/EEGProjects/MotorImagery":{"id":"Examples/EEGProjects/MotorImagery","title":"Motor Imagery","description":"This tutorial was made by Rakesh C Jakati.","sidebar":"docs"},"Examples/EMGProjects/EMG_Chrome_Dino_Game":{"id":"Examples/EMGProjects/EMG_Chrome_Dino_Game","title":"EMG Chrome Dino Game","description":"In this tutorial we will show you how to play the Google Chrome Dinosaur Game without touching your laptop. To do that, we will read EMG data from your arm muscles and find the peaks which correspond to flexing, using them to trigger a jump of the dinosaur.","sidebar":"docs"},"Examples/EMGProjects/EMG_LED":{"id":"Examples/EMGProjects/EMG_LED","title":"EMG-controlled LED","description":"This tutorial is little more involved than the other EMG tutorials. No fear, we\'ve documented every step below. Happy bio-hacking!","sidebar":"docs"},"Examples/EMGProjects/EMG_Tetris":{"id":"Examples/EMGProjects/EMG_Tetris","title":"EMG-controlled Tetris","description":"In this tutorial, we will show you how to make your own muscle-controlled Tetris game. You can now play Tetris on your computer without pressing any keys!","sidebar":"docs"},"Examples/EMGProjects/EMGmusic":{"id":"Examples/EMGProjects/EMGmusic","title":"EMG-controlled Music","description":"In this tutorial, we will show you how to pause and unpause your music without pressing any keys on your laptop keyboard. To do that, we will read the peaks in EMG signals your arm muscles produce when you flex them and use them as a trigger for pausing the music played via Youtube through your computer. Feel free to connect your laptop to a Bluetooth speaker to make the music louder!","sidebar":"docs"},"Examples/EMGProjects/EMGpiano":{"id":"Examples/EMGProjects/EMGpiano","title":"EMG-controlled Piano","description":"In this tutorial, we will show you how to play the piano using just the EMG signals from your fingers! To do that, we will read EMG data from the muscles joining your fingers to your arms and find the peaks which correspond to pressing a key on a piano, using them as a trigger to play a virtual keyboard.","sidebar":"docs"},"Examples/EMGProjects/EMGscrolling":{"id":"Examples/EMGProjects/EMGscrolling","title":"EMG Scrolling","description":"In this tutorial, we will show you how to scroll up and down on your computer screen without touching the keyboard. For that, we will read the peaks in EMG signals your arm muscles produce when you flex them and use them to scroll.","sidebar":"docs"},"Examples/EMGProjects/EMGslideshow":{"id":"Examples/EMGProjects/EMGslideshow","title":"EMG-controlled Slideshow","description":"In this tutorial, we will show you how to scroll through a presentation using your eyes. To do that, we will read EMG data from the muscles around your eyes and find the peaks which correspond to blinking, using them as a trigger to scroll to the next slide. Even though we are using eye blinks in this example, any EMG signals such as those produced by your jaw when you clench it or your arms when you move them can be used.","sidebar":"docs"},"Examples/ExamplesLanding":{"id":"Examples/ExamplesLanding","title":"Example Projects","description":"The Examples directory to the left contains example projects contributed by members of the OpenBCI Community and team. For even more tutorials, head to the tutorials tag in the Community Page!","sidebar":"docs"},"Examples/VideoExperiment":{"id":"Examples/VideoExperiment","title":"Puppies and Kittens Experiment","description":"Welcome to the OpenBCI Puppies and Kittens Experiment designed by Fan Li.","sidebar":"docs"},"FAQ/Cookie":{"id":"FAQ/Cookie","title":"OpenBCI Cookie Policy","description":"What Are Cookies","sidebar":"docs"},"FAQ/DocsUpdate":{"id":"FAQ/DocsUpdate","title":"Docs Website Update","description":"We have recently updated the Docs website! You may be seeing this page if you have attempted to access a page that has moved. You can find the same information using either the dropdowns on the left or the \\"Search Docs\\" function in the top right of this window. Enjoy!","sidebar":"docs"},"FAQ/FAQLanding":{"id":"FAQ/FAQLanding","title":"Frequently Asked Questions","description":"Welcome to our Frequently Asked Questions (FAQ)! Select the appropriate question category to proceed:","sidebar":"docs"},"FAQ/GenFAQ":{"id":"FAQ/GenFAQ","title":"General Frequently Asked Questions","description":"What does OpenBCI stand for?","sidebar":"docs"},"FAQ/HardFAQ":{"id":"FAQ/HardFAQ","title":"Hardware & Software","description":"What do I need to get started?","sidebar":"docs"},"FAQ/HowProductsGoTogether":{"id":"FAQ/HowProductsGoTogether","title":"How OpenBCI products go together?","description":"image","sidebar":"docs"},"FAQ/Liability":{"id":"FAQ/Liability","title":"Liability Policy","description":"Disclaimer of medical, clinical, or diagnostic use","sidebar":"docs"},"FAQ/PaymentFAQ":{"id":"FAQ/PaymentFAQ","title":"Purchases & Payment Processing","description":"Please note all orders ship after full payment. Orders cannot be split between multiple shipments. To make a change to your order, please email support@openbci.com ASAP. We cannot guarantee that we can satisfy the request, but we will do our best if contacted in a timely fashion.","sidebar":"docs"},"FAQ/Privacy":{"id":"FAQ/Privacy","title":"Privacy & Security","description":"Effective June 26, 2018","sidebar":"docs"},"FAQ/Returns":{"id":"FAQ/Returns","title":"RETURNS & REFUNDS","description":"Returns","sidebar":"docs"},"FAQ/ShippingFAQ":{"id":"FAQ/ShippingFAQ","title":"Shipping & Taxes","description":"Where do you ship to?","sidebar":"docs"},"ForDevelopers/FirmwareDevelopment":{"id":"ForDevelopers/FirmwareDevelopment","title":"Firmware Development","description":"Welcome all Firmware Developers! In this document, you can find a list of firmware resources for current boards. This is a great starting point if you are interested in how a board works at the firmware level or an expert user interested in modifying the firmware.","sidebar":"docs"},"ForDevelopers/ForDevelopersLanding":{"id":"ForDevelopers/ForDevelopersLanding","title":"For Developers","description":"The information in this directory will help you start developing with OpenBCI technology.","sidebar":"docs"},"ForDevelopers/HardwareDevelopment":{"id":"ForDevelopers/HardwareDevelopment","title":"Hardware Development","description":"Welcome all Hardware Developers! Are you interested in how an OpenBCI board is made? Do you want to make one yourself or incorporate one into a project? This is the place for you! Here you will find resources, including full schematics, for current and past hardware.","sidebar":"docs"},"ForDevelopers/SoftwareDevelopment":{"id":"ForDevelopers/SoftwareDevelopment","title":"Software Development","description":"Welcome all Software Developers! In this document, we will go over the tools available to assist in integrating OpenBCI hardware with projects in multiple programming languages. Also, we will briefly look at how OpenBCI hardware is integrated into the OpenBCI GUI using Processing).","sidebar":"docs"},"Ganglion/GanglionDataFormat":{"id":"Ganglion/GanglionDataFormat","title":"Ganglion Data Format","description":"This discussion of the OpenBCI data format only applies to the OpenBCI Ganglion. The Ganglion contains a Simblee microcontroller that can both be programmed through the Arduino IDE or over-the-air (OTA). The Simblee has an on-board radio module. The format of the Ganglion data as seen on the PC is defined by a combination of the Arduino code on the Ganglion board and software on your computer. So, if you don\'t like the data format defined here, feel free to change it! In general, and believe us, we tried, you can\'t send more then 100 BLE packets per second. For more info on the byte stream parsing on the computer side, or for a working example, see the NodeJS Ganglion Driver.","sidebar":"docs"},"Ganglion/GanglionLanding":{"id":"Ganglion/GanglionLanding","title":"Ganglion Board","description":"Buy it!","sidebar":"docs"},"Ganglion/GanglionProgram":{"id":"Ganglion/GanglionProgram","title":"Ganglion Programming Tutorial","description":"Please note, you do NOT need to program the Ganglion in order to use it. All OpenBCI boards ship ready to use out of the box. This guide is for users who want to upload their own firmware to the Ganglion or modify existing firmware.","sidebar":"docs"},"Ganglion/GanglionSDK":{"id":"Ganglion/GanglionSDK","title":"Ganglion SDK","description":"The OpenBCI boards communicate using a byte string (mostly ASCII) command protocol. This Doc covers command use for the OpenBCI Ganglion. Further this Doc covers the commands needed in order to alter the radio system. There have been several iterations of the firmware. Please send reset commands to your board to see what firmware you have if you\'re unsure.","sidebar":"docs"},"Ganglion/GanglionSpecs":{"id":"Ganglion/GanglionSpecs","title":"Ganglion Specs","description":"BUY IT!","sidebar":"docs"},"GettingStarted/Biosensing-Setups/ECGSetup":{"id":"GettingStarted/Biosensing-Setups/ECGSetup","title":"Setting up for ECG","description":"This document will show you how to read ECG data (electrical signals from the heart) using OpenBCI hardware and GUI.","sidebar":"docs"},"GettingStarted/Biosensing-Setups/EEGSetup":{"id":"GettingStarted/Biosensing-Setups/EEGSetup","title":"Setting up for EEG","description":"This page will explain the most basic setup to process EEG Data using your OpenBCI board, using our gold cup electrodes.","sidebar":"docs"},"GettingStarted/Biosensing-Setups/EMGSetup":{"id":"GettingStarted/Biosensing-Setups/EMGSetup","title":"Setting up for EMG","description":"This document will show you how to read EMG data (electrical signals from muscles) using OpenBCI hardware and GUI.","sidebar":"docs"},"GettingStarted/Biosensing-Setups/ExGSetup":{"id":"GettingStarted/Biosensing-Setups/ExGSetup","title":"Setting up for EEG, EMG, and ECG at the same time","description":"OpenBCI Cyton+Daisy board offers a wide range of flexibility with more signal channels.","sidebar":"docs"},"GettingStarted/Boards/CytonGS":{"id":"GettingStarted/Boards/CytonGS","title":"Cyton Getting Started Guide","description":"This guide will walk you through setting up your computer to use the Cyton and USB Dongle, using the OpenBCI_GUI Application, and how to get EEG/EMG/EKG from your own body! Please review this guide in its entirety before starting and consult the Cyton Biosensing Tutorial Video for extra guidance. Have fun!","sidebar":"docs"},"GettingStarted/Boards/DaisyGS":{"id":"GettingStarted/Boards/DaisyGS","title":"Daisy Getting Started Guide","description":"This guide will walk you through getting 16-channel input on your Cyton+Daisy Module","sidebar":"docs"},"GettingStarted/Boards/GanglionGS":{"id":"GettingStarted/Boards/GanglionGS","title":"Ganglion Getting Started Guide","description":"Overview","sidebar":"docs"},"GettingStarted/Boards/WiFiGS":{"id":"GettingStarted/Boards/WiFiGS","title":"WiFi Shield Getting Started Guide","description":"Overview","sidebar":"docs"},"GettingStarted/Community/Community":{"id":"GettingStarted/Community/Community","title":"Welcome to the OpenBCI Community","description":"openbci.com/community/","sidebar":"docs"},"GettingStarted/Documentation/DocEdits":{"id":"GettingStarted/Documentation/DocEdits","title":"Editing Docs Guide","description":"This page will explain the process of contributing to the OpenBCI documentation.","sidebar":"docs"},"GettingStarted/GettingStartedLanding":{"id":"GettingStarted/GettingStartedLanding","title":"Getting Started","description":"This directory will show you everything you need to know to get started with OpenBCI.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/BioEra":{"id":"Software/CompatibleThirdPartySoftware/BioEra","title":"BioEra","description":"From the BioEra homepage: BioEra is a visual designer useful for analyzing signals in real time. It can be used with any device with ability to stream data to a computer.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/BrainBay":{"id":"Software/CompatibleThirdPartySoftware/BrainBay","title":"BrainBay","description":"From their OpenBCI tutorials page: BrainBay is an open-source visual programming language (VPL) for rapid prototyping of EEG digital signal processing steps (or data flows.)","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/LSL":{"id":"Software/CompatibleThirdPartySoftware/LSL","title":"Lab Streaming Layer (LSL)","description":"Lab streaming layer is a system for synchronizing streaming data for live analysis or recording. LSL is a good way to send your OpenBCI stream to applications that can record or manipulate the data, such as Matlab (see our Matlab tutorial for using LSL in this context).","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/Matlab":{"id":"Software/CompatibleThirdPartySoftware/Matlab","title":"MATLAB","description":"MATLAB is a powerful numerical computing language and environment that is widely used in a wide variety of academic, research, and industrial applications.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/Neuromore":{"id":"Software/CompatibleThirdPartySoftware/Neuromore","title":"Neuromore","description":"Neuromore is an EEG streaming and processing studio. Like BrainBay and BioEra, it provides a visual designer that can be used to process signals real-time.","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/OpenVibe":{"id":"Software/CompatibleThirdPartySoftware/OpenVibe","title":"OpenViBE","description":"Overview","sidebar":"docs"},"Software/CompatibleThirdPartySoftware/VirtualBox":{"id":"Software/CompatibleThirdPartySoftware/VirtualBox","title":"VirtualBox Windows Guide","description":"Some of the software compatible with OpenBCI products requires a Windows operating system. If you have a non-windows computer, you can still use this software through a Windows virtual machine on VirtualBox.","sidebar":"docs"},"Software/OpenBCISoftware/GUIDocs":{"id":"Software/OpenBCISoftware/GUIDocs","title":"The OpenBCI GUI","description":"image","sidebar":"docs"},"Software/OpenBCISoftware/GUIWidgets":{"id":"Software/OpenBCISoftware/GUIWidgets","title":"GUI Widget Guide","description":"What is a GUI Widget?","sidebar":"docs"},"Software/OpenBCISoftware/NeuroFly_Toolkit":{"id":"Software/OpenBCISoftware/NeuroFly_Toolkit","title":"NeuroFly Toolkit","description":"This tutorial will show you how to control a joystick using EMG data with the OpenBCI GUI. You can then use this customizable, muscle-activated joystick for any purpose of your choosing! OpenBCI used this to control a drone in the 2023 OpenBCI TED Talk.","sidebar":"docs"},"Software/SoftwareLanding":{"id":"Software/SoftwareLanding","title":"Compatible Software","description":"OpenBCI Software","sidebar":"docs"},"ThirdParty/EmotiBit/EmotiBit_Guide":{"id":"ThirdParty/EmotiBit/EmotiBit_Guide","title":"EmotiBit Guide","description":"Overview","sidebar":"docs"},"ThirdParty/IDUN_Dryode/Dryode":{"id":"ThirdParty/IDUN_Dryode/Dryode","title":"IDUN Dryode","description":"Overview","sidebar":"docs"},"ThirdParty/Myoware/MyoWareCyton":{"id":"ThirdParty/Myoware/MyoWareCyton","title":"MyoWare OpenBCI Integration (Cyton Board)","description":"The Myoware 2.0 board cannot be used with the Ganglion board. If you have purchased a Myoware 2.0 board with the intention of using it with the Ganglion board, please contact Customer support at contact@openbci.com","sidebar":"docs"},"ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing":{"id":"ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing","title":"Pulse Sensor Guide","description":"The Pulse Sensor can be connected to the Cyton or any Arduino board to easily obtain your heart rate using photoplethysmogram (PPG).","sidebar":"docs"},"ThirdParty/ThinkPulse/ThinkPulse":{"id":"ThirdParty/ThinkPulse/ThinkPulse","title":"ThinkPulse Getting Started Guide","description":"Available exclusively worldwide only on the OpenBCI\xae store.","sidebar":"docs"},"ThirdParty/ThirdPartyLanding":{"id":"ThirdParty/ThirdPartyLanding","title":"Third-Party Hardware","description":"The directory to the left contains documents to explain the integration between OpenBCI and compatible third-party hardware. This landing page summarizes the variety of sampling modalities!","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiAPI":{"id":"ThirdParty/WiFiShield/WiFiAPI","title":"OpenBCI WiFi Shield API","description":"The OpenBCI Wifi Shield seeks to offer a plug and play Wifi solution for the OpenBCI Cyton and Ganglion.","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiLanding":{"id":"ThirdParty/WiFiShield/WiFiLanding","title":"OpenBCI WiFi","description":"BUY IT!","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiProgam":{"id":"ThirdParty/WiFiShield/WiFiProgam","title":"Wifi Shield Programming Tutorial","description":"Overview","sidebar":"docs"},"ThirdParty/WiFiShield/WiFiSDK":{"id":"ThirdParty/WiFiShield/WiFiSDK","title":"OpenBCI Wifi SDK","description":"The purpose of this doc is to describe what\'s required to interface another micro-controller with the WiFi Shield.","sidebar":"docs"},"Troubleshooting/FTDI_Fix_Linux":{"id":"Troubleshooting/FTDI_Fix_Linux","title":"FTDI Buffer Fix on Linux","description":"Summary","sidebar":"docs"},"Troubleshooting/FTDI_Fix_Mac":{"id":"Troubleshooting/FTDI_Fix_Mac","title":"FTDI Buffer Fix on OS X","description":"Summary","sidebar":"docs"},"Troubleshooting/FTDI_Fix_Windows":{"id":"Troubleshooting/FTDI_Fix_Windows","title":"FTDI Buffer Fix on Windows","description":"Tested on:","sidebar":"docs"},"Troubleshooting/GUI_Troubleshooting":{"id":"Troubleshooting/GUI_Troubleshooting","title":"GUI Troubleshooting","description":"The GUI Console Log","sidebar":"docs"},"Troubleshooting/MacOSGanglionBLEWorkaround":{"id":"Troubleshooting/MacOSGanglionBLEWorkaround","title":"MacOS Ganglion BLE Workaround","description":"In later versions of MacOS (generally MacOS 11+) there is an issue where Bluetooth permissions are not requested by the application. This prevents the embedded native BLE library from accessing the Bluetooth adapter and therefore Ganglion boards (and other Bluetooth devices) cannot be found. This issue appears to be related to application hardening requirements introduced in MacOS 10.14.5. Most importantly, the JDK 8 version that ships with Processing 3.5.4 and earlier is not notarized and therefore cannot request permissions from the OS.","sidebar":"docs"},"Troubleshooting/minimizingNoise":{"id":"Troubleshooting/minimizingNoise","title":"Minimizing Noise","description":"Are you getting \\"noisy\\" data from your device? There are several possible reasons for this. Let\'s go through some simple troubleshooting steps that resolve most issues.","sidebar":"docs"},"Troubleshooting/TroubleshootingLanding":{"id":"Troubleshooting/TroubleshootingLanding","title":"Troubleshooting Landing","description":"The guides below offer tips on common hardware and software issues and how to fix them.","sidebar":"docs"},"Welcome":{"id":"Welcome","title":"Welcome to the OpenBCI Community","description":"Welcome to the OpenBCI Learning Pages! Here you will find a wide range of guides and tutorials that are intended to teach you how to use your OpenBCI gear. If you run into issues or have additional questions, head to our Forum with daily active users. Check out the Community Page for project ideas!","sidebar":"docs"}}}')}}]); \ No newline at end of file diff --git a/assets/js/main.51d75156.js b/assets/js/main.51d75156.js new file mode 100644 index 000000000..fb344c6c7 --- /dev/null +++ b/assets/js/main.51d75156.js @@ -0,0 +1,2 @@ +/*! For license information please see main.51d75156.js.LICENSE.txt */ +(self.webpackChunk=self.webpackChunk||[]).push([[179],{20830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(67294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},99782:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={title:"OpenBCI Documentation",tagline:"OpenBCI Docs",url:"https://openbci.github.io",baseUrl:"/",organizationName:"OpenBCI",projectName:"Documentation",scripts:["https://buttons.github.io/buttons.js"],favicon:"img/favicon_large.ico",customFields:{gaGtag:!0},onBrokenLinks:"log",onBrokenMarkdownLinks:"log",trailingSlash:!0,presets:[["@docusaurus/preset-classic",{docs:{showLastUpdateAuthor:!1,showLastUpdateTime:!0,editUrl:"https://github.com/OpenBCI/Documentation/edit/master/website/",path:"docs",sidebarPath:"/home/runner/work/Documentation/Documentation/website/sidebars.json",routeBasePath:"/"},blog:{path:"blog"},theme:{customCss:["/home/runner/work/Documentation/Documentation/website/src/css/customTheme.css"]},gtag:{trackingID:"G-HVMLC0ZWWS"}}]],plugins:[],themeConfig:{navbar:{title:"OpenBCI Documentation",logo:{src:"img/open-bci-gear.svg"},items:[{href:"https://openbci.com",label:"Main Site",position:"right"},{href:"https://shop.openbci.com",label:"Shop",position:"right"},{href:"https://openbci.com/forum/",label:"Forum",position:"right"},{to:"/",label:"Documentation",position:"right"},{href:"https://github.com/OpenBCI",label:"Github",position:"right"},{to:"/citations",label:"Citations",position:"right"}],hideOnScroll:!1},image:"https://openbci.github.io/Documentation/img/UC-production-1140x424.jpg",metadata:[{name:"thumbnail",content:"https://docs.openbci.com/img/openbci-logo-web.png"}],footer:{links:[],copyright:"Copyright \xa9 2023 OpenBCI",logo:{src:"img/open-bci-gear-blue.svg"},style:"light"},algolia:{apiKey:"19411ba246745c95db0bff87cfed97b0",indexName:"openbci",placeholder:"Search Docs",algoliaOptions:{},contextualSearch:!1,appId:"BH4D9OD16A",searchParameters:{}},colorMode:{defaultMode:"light",disableSwitch:!1,respectPrefersColorScheme:!1,switchConfig:{darkIcon:"\ud83c\udf1c",darkIconStyle:{},lightIcon:"\ud83c\udf1e",lightIconStyle:{}}},docs:{versionPersistence:"localStorage"},prism:{additionalLanguages:[]},hideableSidebar:!1,tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},baseUrlIssueBanner:!0,i18n:{defaultLocale:"en",locales:["en"],localeConfigs:{}},onDuplicateRoutes:"warn",staticDirectories:["static"],themes:[],titleDelimiter:"|",noIndex:!1}},52067:(e,t,n)=>{"use strict";var r=n(67294),a=n(73935),o=n(73727),i=n(68356),l=n.n(i);function s(e){var t=e.error,n=e.retry,a=e.pastDelay;return t?r.createElement("div",{style:{align:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}const u=JSON.parse('{"/blog/-ef8":{"component":"a6aa9e1f","sidebar":"814f3328","items":[{"content":"02589645"}],"metadata":"b2b675dd"},"/blog/2016/03/11/blog-post/-a04":{"component":"ccc49370","sidebar":"814f3328","content":"bf9e930a"},"/blog/archive/-38a":{"component":"9e4087bc","archive":"b2f554cd"},"/citations/-ff7":{"component":"bfde6a7e","config":"5e9f5e1a"},"/help/-4ff":{"component":"7e37206e","config":"5e9f5e1a"},"/search/-e07":{"component":"156572e4"},"/-606":{"component":"1be78505","versionMetadata":"935f2afb"},"/-8e8":{"component":"17896441","content":"7afa52e9"},"/AddOns/AddOnLanding/-5b7":{"component":"17896441","content":"90780899"},"/AddOns/Electrodes/ElectrodesLanding/-67c":{"component":"17896441","content":"da647ae7"},"/AddOns/Headwear/ElectrodeCap/-11f":{"component":"17896441","content":"e99cad7e"},"/AddOns/Headwear/GelfreeElectrodeCap/-45c":{"component":"17896441","content":"c3d7dc26"},"/AddOns/Headwear/HeadBand/-5ae":{"component":"17896441","content":"cdc07f54"},"/AddOns/Headwear/MarkIV/-0b5":{"component":"17896441","content":"f0a397b9"},"/Cyton/CytonDataFormat/-b6e":{"component":"17896441","content":"4622fd49"},"/Cyton/CytonExternal/-bbb":{"component":"17896441","content":"fd5221e6"},"/Cyton/CytonLanding/-e78":{"component":"17896441","content":"7e984ee4"},"/Cyton/CytonProgram/-89d":{"component":"17896441","content":"e5d2a39f"},"/Cyton/CytonRadios/-ea0":{"component":"17896441","content":"5933e9ab"},"/Cyton/CytonSDCard/-ffd":{"component":"17896441","content":"f5bedc00"},"/Cyton/CytonSDK/-aeb":{"component":"17896441","content":"8e8fbadf"},"/Cyton/CytonSpecs/-b29":{"component":"17896441","content":"57d8184d"},"/Deprecated/8bitBoardDep/-f47":{"component":"17896441","content":"de09c3b8"},"/Deprecated/DeprecatedLanding/-34f":{"component":"17896441","content":"71c3c442"},"/Deprecated/Hub/-0f0":{"component":"17896441","content":"bf37710e"},"/Deprecated/MarkIII/-f72":{"component":"17896441","content":"b7fcae77"},"/Deprecated/MyoCyton/-7cc":{"component":"17896441","content":"713e7afa"},"/Deprecated/MyoGanglion/-438":{"component":"17896441","content":"cd601551"},"/Deprecated/Python/-9d1":{"component":"17896441","content":"95b6f374"},"/Deprecated/SpiderclawDep/-faf":{"component":"17896441","content":"ca9bf8fa"},"/Deprecated/UltracortexMark1Dep/-07e":{"component":"17896441","content":"9e3b9512"},"/Deprecated/UltracortexMark2Dep/-c92":{"component":"17896441","content":"af560b86"},"/Deprecated/UltracortexMark3_NovaDep/-bac":{"component":"17896441","content":"b2ec28d0"},"/Deprecated/UltracortexMark3Dep/-530":{"component":"17896441","content":"c2e793b4"},"/Examples/CommunityPageProjects/-7e6":{"component":"17896441","content":"c2d4508c"},"/Examples/EEGProjects/FocusArduino/-2f6":{"component":"17896441","content":"a3380812"},"/Examples/EEGProjects/MotorImagery/-d42":{"component":"17896441","content":"fa3759a2"},"/Examples/EMGProjects/EMG_Chrome_Dino_Game/-a62":{"component":"17896441","content":"11423056"},"/Examples/EMGProjects/EMG_LED/-d5e":{"component":"17896441","content":"3bed7388"},"/Examples/EMGProjects/EMG_Tetris/-a7d":{"component":"17896441","content":"436b93f3"},"/Examples/EMGProjects/EMGmusic/-dc8":{"component":"17896441","content":"66f0a00e"},"/Examples/EMGProjects/EMGpiano/-218":{"component":"17896441","content":"34c051f1"},"/Examples/EMGProjects/EMGscrolling/-235":{"component":"17896441","content":"f7b346af"},"/Examples/EMGProjects/EMGslideshow/-062":{"component":"17896441","content":"5b209adb"},"/Examples/ExamplesLanding/-1c6":{"component":"17896441","content":"151efb24"},"/Examples/VideoExperiment/-dd0":{"component":"17896441","content":"9cc882f3"},"/FAQ/Conduct/-e1d":{"component":"17896441","content":"69fc568b"},"/FAQ/Cookie/-b58":{"component":"17896441","content":"9850f47c"},"/FAQ/DocsUpdate/-21c":{"component":"17896441","content":"0d754ef2"},"/FAQ/FAQLanding/-385":{"component":"17896441","content":"e6ba95e8"},"/FAQ/GenFAQ/-057":{"component":"17896441","content":"70bb90d6"},"/FAQ/HardFAQ/-a6c":{"component":"17896441","content":"48416048"},"/FAQ/HowProductsGoTogether/-f76":{"component":"17896441","content":"cfb429bb"},"/FAQ/Liability/-9ae":{"component":"17896441","content":"8ff634cd"},"/FAQ/PaymentFAQ/-28e":{"component":"17896441","content":"b1c4dd8e"},"/FAQ/Privacy/-33c":{"component":"17896441","content":"34f41b76"},"/FAQ/Returns/-f0c":{"component":"17896441","content":"f8c20308"},"/FAQ/ShippingFAQ/-3c2":{"component":"17896441","content":"40b8996d"},"/ForDevelopers/FirmwareDevelopment/-24e":{"component":"17896441","content":"2526ab21"},"/ForDevelopers/ForDevelopersLanding/-663":{"component":"17896441","content":"87ca6914"},"/ForDevelopers/HardwareDevelopment/-fa9":{"component":"17896441","content":"bccd56f7"},"/ForDevelopers/SoftwareDevelopment/-91e":{"component":"17896441","content":"53cc4ae7"},"/Ganglion/GanglionDataFormat/-c30":{"component":"17896441","content":"db6c7d05"},"/Ganglion/GanglionLanding/-f2a":{"component":"17896441","content":"e88da605"},"/Ganglion/GanglionProgram/-cd4":{"component":"17896441","content":"1836639f"},"/Ganglion/GanglionSDK/-468":{"component":"17896441","content":"3540373b"},"/Ganglion/GanglionSpecs/-e64":{"component":"17896441","content":"4f548a4b"},"/GettingStarted/Biosensing-Setups/ECGSetup/-fa4":{"component":"17896441","content":"daf02663"},"/GettingStarted/Biosensing-Setups/EEGSetup/-4aa":{"component":"17896441","content":"dc5380ea"},"/GettingStarted/Biosensing-Setups/EMGSetup/-bfa":{"component":"17896441","content":"d4b262eb"},"/GettingStarted/Biosensing-Setups/ExGSetup/-649":{"component":"17896441","content":"db6581e7"},"/GettingStarted/Boards/CytonGS/-a9d":{"component":"17896441","content":"41f5aae9"},"/GettingStarted/Boards/DaisyGS/-7be":{"component":"17896441","content":"2cffd42f"},"/GettingStarted/Boards/GanglionGS/-65f":{"component":"17896441","content":"b766078a"},"/GettingStarted/Boards/WiFiGS/-fa2":{"component":"17896441","content":"7d29fede"},"/GettingStarted/Community/Community/-ca3":{"component":"17896441","content":"8adb28a7"},"/GettingStarted/Documentation/DocEdits/-6bb":{"component":"17896441","content":"277de663"},"/GettingStarted/GettingStartedLanding/-bb5":{"component":"17896441","content":"2ffaf93e"},"/Software/CompatibleThirdPartySoftware/BioEra/-b60":{"component":"17896441","content":"feddef67"},"/Software/CompatibleThirdPartySoftware/BrainBay/-051":{"component":"17896441","content":"a676f095"},"/Software/CompatibleThirdPartySoftware/LSL/-bb0":{"component":"17896441","content":"ba721d5b"},"/Software/CompatibleThirdPartySoftware/Matlab/-eda":{"component":"17896441","content":"1c20b5be"},"/Software/CompatibleThirdPartySoftware/Neuromore/-ecc":{"component":"17896441","content":"e79258ab"},"/Software/CompatibleThirdPartySoftware/OpenVibe/-f6a":{"component":"17896441","content":"de741a90"},"/Software/CompatibleThirdPartySoftware/VirtualBox/-8bb":{"component":"17896441","content":"2fb3f022"},"/Software/OpenBCISoftware/GUIDocs/-b07":{"component":"17896441","content":"fd1cf8f8"},"/Software/OpenBCISoftware/GUIWidgets/-ddf":{"component":"17896441","content":"066d7e8a"},"/Software/OpenBCISoftware/NeuroFly_Toolkit/-ce6":{"component":"17896441","content":"a36a5894"},"/Software/SoftwareLanding/-4cc":{"component":"17896441","content":"46d86098"},"/ThirdParty/EmotiBit/EmotiBit_Guide/-9dd":{"component":"17896441","content":"fa7ae40f"},"/ThirdParty/IDUN_Dryode/Dryode/-72d":{"component":"17896441","content":"c51e9294"},"/ThirdParty/Myoware/MyoWareCyton/-453":{"component":"17896441","content":"077ea582"},"/ThirdParty/Pulse_Sensor/Pulse_Sensor_Landing/-400":{"component":"17896441","content":"7fd3f1dc"},"/ThirdParty/ThinkPulse/ThinkPulse/-928":{"component":"17896441","content":"e02a2bae"},"/ThirdParty/ThirdPartyLanding/-fa9":{"component":"17896441","content":"232fc90b"},"/ThirdParty/WiFiShield/WiFiAPI/-d5f":{"component":"17896441","content":"793004bb"},"/ThirdParty/WiFiShield/WiFiLanding/-b61":{"component":"17896441","content":"2ca91f42"},"/ThirdParty/WiFiShield/WiFiProgam/-a46":{"component":"17896441","content":"0d0dd011"},"/ThirdParty/WiFiShield/WiFiSDK/-153":{"component":"17896441","content":"1f77940f"},"/Troubleshooting/FTDI_Fix_Linux/-7dc":{"component":"17896441","content":"cac59f3e"},"/Troubleshooting/FTDI_Fix_Mac/-3fa":{"component":"17896441","content":"852b53c9"},"/Troubleshooting/FTDI_Fix_Windows/-74e":{"component":"17896441","content":"84c50c46"},"/Troubleshooting/GUI_Troubleshooting/-b25":{"component":"17896441","content":"7377c08e"},"/Troubleshooting/MacOSGanglionBLEWorkaround/-cfa":{"component":"17896441","content":"4e1f66d9"},"/Troubleshooting/minimizingNoise/-d84":{"component":"17896441","content":"c9253d27"},"/Troubleshooting/TroubleshootingLanding/-ffe":{"component":"17896441","content":"218e374c"}}'),c={"02589645":[function(){return n.e(1009).then(n.bind(n,50672))},"@site/blog/2016-03-11-blog-post.md?truncated=true",50672],"066d7e8a":[function(){return n.e(1479).then(n.bind(n,48021))},"@site/docs/Software/OpenBCISoftware/02_GUI_Widget_Guide.md",48021],"077ea582":[function(){return n.e(9572).then(n.bind(n,72314))},"@site/docs/ThirdParty/Myoware/MyoWare_Cyton_Tutorial.md",72314],"0d0dd011":[function(){return n.e(7757).then(n.bind(n,74878))},"@site/docs/ThirdParty/WiFiShield/12-Wifi_Programming_Tutorial.md",74878],"0d754ef2":[function(){return n.e(7514).then(n.bind(n,38762))},"@site/docs/FAQ/Docs_Update.md",38762],11423056:[function(){return n.e(2961).then(n.bind(n,55423))},"@site/docs/Examples/EMGProjects/05-EMG_Chrome_Dino_Game.md",55423],"151efb24":[function(){return n.e(4038).then(n.bind(n,58754))},"@site/docs/Examples/00-ExamplesLanding.md",58754],"156572e4":[function(){return Promise.all([n.e(532),n.e(642)]).then(n.bind(n,39172))},"/home/runner/work/Documentation/Documentation/website/node_modules/@docusaurus/theme-search-algolia/lib/theme/SearchPage/index.js",39172],17896441:[function(){return Promise.all([n.e(532),n.e(7918)]).then(n.bind(n,16237))},"@theme/DocItem",16237],"1836639f":[function(){return n.e(1633).then(n.bind(n,22389))},"@site/docs/Ganglion/09-Ganglion_Programming_Tutorial.md",22389],"1be78505":[function(){return Promise.all([n.e(532),n.e(3829),n.e(9514)]).then(n.bind(n,85642))},"@theme/DocPage",85642],"1c20b5be":[function(){return n.e(4901).then(n.bind(n,34839))},"@site/docs/Software/CompatibleThirdPartySoftware/01-Matlab.md",34839],"1f77940f":[function(){return n.e(815).then(n.bind(n,97729))},"@site/docs/ThirdParty/WiFiShield/08-OpenBCI_Wifi_SDK.md",97729],"218e374c":[function(){return n.e(6689).then(n.bind(n,13709))},"@site/docs/Troubleshooting/00-TroubleshootingLanding.md",13709],"232fc90b":[function(){return n.e(8530).then(n.bind(n,85361))},"@site/docs/ThirdParty/ThirdPartyLanding.md",85361],"2526ab21":[function(){return n.e(2155).then(n.bind(n,65220))},"@site/docs/ForDevelopers/02-FirmwareDevelopment.md",65220],"277de663":[function(){return n.e(938).then(n.bind(n,75347))},"@site/docs/GettingStarted/Documentation/01-Doc_Edits.md",75347],"2ca91f42":[function(){return n.e(2623).then(n.bind(n,56362))},"@site/docs/ThirdParty/WiFiShield/01-Wifi.md",56362],"2cffd42f":[function(){return n.e(4775).then(n.bind(n,25752))},"@site/docs/GettingStarted/Boards/011-Daisy_Getting_Started_Guide.md",25752],"2fb3f022":[function(){return n.e(117).then(n.bind(n,71635))},"@site/docs/Software/CompatibleThirdPartySoftware/07-VirtualBox.md",71635],"2ffaf93e":[function(){return n.e(5687).then(n.bind(n,51538))},"@site/docs/GettingStarted/00-GettingStartedLanding.md",51538],"34c051f1":[function(){return n.e(486).then(n.bind(n,61148))},"@site/docs/Examples/EMGProjects/EMG_Controlled_Piano.md",61148],"34f41b76":[function(){return n.e(3558).then(n.bind(n,44832))},"@site/docs/FAQ/Privacy_Policy.md",44832],"3540373b":[function(){return n.e(6146).then(n.bind(n,99977))},"@site/docs/Ganglion/06-OpenBCI_Ganglion_SDK.md",99977],"3bed7388":[function(){return n.e(7681).then(n.bind(n,18060))},"@site/docs/Examples/EMGProjects/04-EMG_LED.md",18060],"40b8996d":[function(){return n.e(7133).then(n.bind(n,23086))},"@site/docs/FAQ/05-ShippingFAQ.md",23086],"41f5aae9":[function(){return n.e(4372).then(n.bind(n,19584))},"@site/docs/GettingStarted/Boards/01-Cyton_Getting_Started_Guide.md",19584],"436b93f3":[function(){return n.e(3482).then(n.bind(n,7286))},"@site/docs/Examples/EMGProjects/Tetris_Tutorial.md",7286],"4622fd49":[function(){return n.e(116).then(n.bind(n,72382))},"@site/docs/Cyton/03-Cyton_Data_Format.md",72382],"46d86098":[function(){return n.e(5013).then(n.bind(n,98212))},"@site/docs/Software/SoftwareLanding.md",98212],48416048:[function(){return n.e(7613).then(n.bind(n,51597))},"@site/docs/FAQ/03-HardwareFAQ.md",51597],"4e1f66d9":[function(){return n.e(3981).then(n.bind(n,27))},"@site/docs/Troubleshooting/MacOS_Ganglion_BLE_Workaround.md",27],"4f548a4b":[function(){return n.e(1243).then(n.bind(n,30526))},"@site/docs/Ganglion/02-Ganglion.md",30526],"53cc4ae7":[function(){return n.e(237).then(n.bind(n,59749))},"@site/docs/ForDevelopers/01-SoftwareDevelopment.md",59749],"57d8184d":[function(){return n.e(772).then(n.bind(n,8002))},"@site/docs/Cyton/02-Cyton.md",8002],"5933e9ab":[function(){return n.e(5158).then(n.bind(n,5838))},"@site/docs/Cyton/06-Cyton_Radios_Programming_Tutorial.md",5838],"5b209adb":[function(){return n.e(4474).then(n.bind(n,76154))},"@site/docs/Examples/EMGProjects/03-EMG_Controlled_Slideshow.md",76154],"5e9f5e1a":[function(){return Promise.resolve().then(n.bind(n,99782))},"@generated/docusaurus.config",99782],"66f0a00e":[function(){return n.e(3560).then(n.bind(n,29357))},"@site/docs/Examples/EMGProjects/02-EMG_Controlled_Music.md",29357],"69fc568b":[function(){return n.e(7282).then(n.bind(n,46551))},"@site/docs/FAQ/Code_Of_Conduct.md",46551],"70bb90d6":[function(){return n.e(2736).then(n.bind(n,29190))},"@site/docs/FAQ/01-GeneralFrequentlyAskedQuestions.md",29190],"713e7afa":[function(){return n.e(7564).then(n.bind(n,71983))},"@site/docs/Deprecated/14-MyoWare_Integration.md",71983],"71c3c442":[function(){return n.e(8624).then(n.bind(n,40646))},"@site/docs/Deprecated/01-DeprecatedDocs.md",40646],"7377c08e":[function(){return n.e(7085).then(n.bind(n,80301))},"@site/docs/Troubleshooting/02-GUI_Troubleshooting.md",80301],"793004bb":[function(){return n.e(4695).then(n.bind(n,44622))},"@site/docs/ThirdParty/WiFiShield/03-OpenBCI_Wifi_Server.md",44622],"7afa52e9":[function(){return n.e(7994).then(n.bind(n,32814))},"@site/docs/Welcome.md",32814],"7d29fede":[function(){return n.e(7816).then(n.bind(n,29368))},"@site/docs/GettingStarted/Boards/03-Wifi_Getting_Started_Guide.md",29368],"7e37206e":[function(){return n.e(2740).then(n.bind(n,75401))},"@site/src/pages/help.js",75401],"7e984ee4":[function(){return n.e(3713).then(n.bind(n,40990))},"@site/docs/Cyton/01-CytonBoard.md",40990],"7fd3f1dc":[function(){return n.e(5553).then(n.bind(n,64901))},"@site/docs/ThirdParty/Pulse_Sensor/Pulse_Sensor_Guide.md",64901],"814f3328":[function(){return n.e(2535).then(n.t.bind(n,45641,19))},"~blog/default/blog-post-list-prop-default.json",45641],"84c50c46":[function(){return n.e(1056).then(n.bind(n,38391))},"@site/docs/Troubleshooting/04-FTDI_Fix_Windows.md",38391],"852b53c9":[function(){return n.e(2857).then(n.bind(n,79053))},"@site/docs/Troubleshooting/05-FTDI_Driver_Fix_Mac.md",79053],"87ca6914":[function(){return n.e(3341).then(n.bind(n,80551))},"@site/docs/ForDevelopers/00-ForDevelopersLanding.md",80551],"8adb28a7":[function(){return n.e(5613).then(n.bind(n,92277))},"@site/docs/GettingStarted/Community/13-Community_Instructions.md",92277],"8e8fbadf":[function(){return n.e(6103).then(n.bind(n,13685))},"@site/docs/Cyton/04-OpenBCI_Cyton_SDK.md",13685],"8ff634cd":[function(){return n.e(672).then(n.bind(n,75236))},"@site/docs/FAQ/Liability_Policy.md",75236],90780899:[function(){return n.e(1024).then(n.bind(n,11943))},"@site/docs/AddOns/00-AddOnLanding.md",11943],"935f2afb":[function(){return n.e(53).then(n.t.bind(n,1109,19))},"~docs/default/version-current-metadata-prop-751.json",1109],"95b6f374":[function(){return n.e(70).then(n.bind(n,93544))},"@site/docs/Deprecated/08-OpenBCI_Python.md",93544],"9850f47c":[function(){return n.e(5443).then(n.bind(n,99764))},"@site/docs/FAQ/Cookie_Policy.md",99764],"9cc882f3":[function(){return n.e(6162).then(n.bind(n,81818))},"@site/docs/Examples/Video_Experiment.md",81818],"9e3b9512":[function(){return n.e(8593).then(n.bind(n,70935))},"@site/docs/Deprecated/04-UltracortexMark1.md",70935],"9e4087bc":[function(){return n.e(3608).then(n.bind(n,63012))},"@theme/BlogArchivePage",63012],a3380812:[function(){return n.e(921).then(n.bind(n,75373))},"@site/docs/Examples/EEGProjects/17-Arduino_Focus_Example.md",75373],a36a5894:[function(){return n.e(1572).then(n.bind(n,28778))},"@site/docs/Software/OpenBCISoftware/NeuroFly_Toolkit.md",28778],a676f095:[function(){return n.e(6404).then(n.bind(n,70194))},"@site/docs/Software/CompatibleThirdPartySoftware/05-BrainBay.md",70194],a6aa9e1f:[function(){return Promise.all([n.e(532),n.e(3829),n.e(3089)]).then(n.bind(n,2754))},"@theme/BlogListPage",2754],af560b86:[function(){return n.e(323).then(n.bind(n,3152))},"@site/docs/Deprecated/05-UltracortexMark2.md",3152],b1c4dd8e:[function(){return n.e(133).then(n.bind(n,61861))},"@site/docs/FAQ/04-PaymentFAQ.md",61861],b2b675dd:[function(){return n.e(533).then(n.t.bind(n,28017,19))},"~blog/default/blog-c06.json",28017],b2ec28d0:[function(){return n.e(9252).then(n.bind(n,61032))},"@site/docs/Deprecated/07-UltracortexMark3_Nova.md",61032],b2f554cd:[function(){return n.e(1477).then(n.t.bind(n,30010,19))},"~blog/default/blog-archive-80c.json",30010],b766078a:[function(){return n.e(9445).then(n.bind(n,40912))},"@site/docs/GettingStarted/Boards/02-Ganglion_Getting_Started_Guide.md",40912],b7fcae77:[function(){return n.e(8210).then(n.bind(n,43452))},"@site/docs/Deprecated/02-Ultracortex-Mark-III-Nova-Revised.md",43452],ba721d5b:[function(){return n.e(989).then(n.bind(n,74175))},"@site/docs/Software/CompatibleThirdPartySoftware/04-LSL.md",74175],bccd56f7:[function(){return n.e(3797).then(n.bind(n,32139))},"@site/docs/ForDevelopers/03-HardwareDevelopment.md",32139],bf37710e:[function(){return n.e(9593).then(n.bind(n,65873))},"@site/docs/Deprecated/OpenBCI_Hub.md",65873],bf9e930a:[function(){return n.e(2048).then(n.bind(n,97393))},"@site/blog/2016-03-11-blog-post.md",97393],bfde6a7e:[function(){return n.e(5147).then(n.bind(n,75084))},"@site/src/pages/citations.js",75084],c2d4508c:[function(){return n.e(2620).then(n.bind(n,47927))},"@site/docs/Examples/16-Community_Page_Projects.md",47927],c2e793b4:[function(){return n.e(7748).then(n.bind(n,68605))},"@site/docs/Deprecated/06-UltracortexMark3.md",68605],c3d7dc26:[function(){return n.e(4223).then(n.bind(n,78369))},"@site/docs/AddOns/Headwear/Gelfree_Electrode_Cap_Tutorial.md",78369],c51e9294:[function(){return n.e(4262).then(n.bind(n,38897))},"@site/docs/ThirdParty/IDUN_Dryode/Dryode_Guide.md",38897],c9253d27:[function(){return n.e(5136).then(n.bind(n,23742))},"@site/docs/Troubleshooting/01-MinimizingNoise.md",23742],ca9bf8fa:[function(){return n.e(5599).then(n.bind(n,8577))},"@site/docs/Deprecated/02-Spiderclaw.md",8577],cac59f3e:[function(){return n.e(3120).then(n.bind(n,25090))},"@site/docs/Troubleshooting/03-FTDI_Fix_Linux.md",25090],ccc49370:[function(){return Promise.all([n.e(532),n.e(3829),n.e(1080)]).then(n.bind(n,39360))},"@theme/BlogPostPage",39360],cd601551:[function(){return n.e(693).then(n.bind(n,30989))},"@site/docs/Deprecated/15-MyoWare_Integration_Ganglion.md",30989],cdc07f54:[function(){return n.e(5212).then(n.bind(n,2548))},"@site/docs/AddOns/Headwear/03-Headband_Tutorial.md",2548],cfb429bb:[function(){return n.e(7049).then(n.bind(n,59115))},"@site/docs/FAQ/02-HowProductsGoTogether.md",59115],d4b262eb:[function(){return n.e(4108).then(n.bind(n,3672))},"@site/docs/GettingStarted/Biosensing-Setups/02-EMG-Setup.md",3672],da647ae7:[function(){return n.e(3924).then(n.bind(n,18945))},"@site/docs/AddOns/Electrodes/00-ElectrodesLanding.md",18945],daf02663:[function(){return n.e(1644).then(n.bind(n,80099))},"@site/docs/GettingStarted/Biosensing-Setups/03-ECG-Setup.md",80099],db6581e7:[function(){return n.e(5686).then(n.bind(n,63790))},"@site/docs/GettingStarted/Biosensing-Setups/04-ExG-Setup.md",63790],db6c7d05:[function(){return n.e(4788).then(n.bind(n,36213))},"@site/docs/Ganglion/08-Ganglion_Data_Format.md",36213],dc5380ea:[function(){return n.e(9346).then(n.bind(n,62659))},"@site/docs/GettingStarted/Biosensing-Setups/01-EEG-Setup.md",62659],de09c3b8:[function(){return n.e(4391).then(n.bind(n,24911))},"@site/docs/Deprecated/03-8bitBoard.md",24911],de741a90:[function(){return n.e(1380).then(n.bind(n,73496))},"@site/docs/Software/CompatibleThirdPartySoftware/03-OpenViBE.md",73496],e02a2bae:[function(){return n.e(7169).then(n.bind(n,62413))},"@site/docs/ThirdParty/ThinkPulse/ThinkPulse_Getting_Started.md",62413],e5d2a39f:[function(){return n.e(8549).then(n.bind(n,3398))},"@site/docs/Cyton/05-Cyton_Board_Programming_Tutorial.md",3398],e6ba95e8:[function(){return n.e(3731).then(n.bind(n,79763))},"@site/docs/FAQ/00-FAQ.md",79763],e79258ab:[function(){return n.e(1095).then(n.bind(n,28385))},"@site/docs/Software/CompatibleThirdPartySoftware/02-Neuromore.md",28385],e88da605:[function(){return n.e(9072).then(n.bind(n,27158))},"@site/docs/Ganglion/01-GanglionBoard.md",27158],e99cad7e:[function(){return n.e(219).then(n.bind(n,62339))},"@site/docs/AddOns/Headwear/04-Electrode_Cap_Tutorial.md",62339],f0a397b9:[function(){return n.e(2425).then(n.bind(n,96069))},"@site/docs/AddOns/Headwear/01-Ultracortex-Mark-IV.md",96069],f5bedc00:[function(){return n.e(8915).then(n.bind(n,73872))},"@site/docs/Cyton/09-Using_SD_Card_with_OpenBCI.md",73872],f7b346af:[function(){return n.e(1114).then(n.bind(n,51944))},"@site/docs/Examples/EMGProjects/01-EMG_Scrolling.md",51944],f8c20308:[function(){return n.e(2944).then(n.bind(n,90251))},"@site/docs/FAQ/Refund_Policy.md",90251],fa3759a2:[function(){return n.e(7340).then(n.bind(n,25773))},"@site/docs/Examples/EEGProjects/20-Motor_Imagery.md",25773],fa7ae40f:[function(){return n.e(2766).then(n.bind(n,81353))},"@site/docs/ThirdParty/EmotiBit/EmotiBit_Guide.md",81353],fd1cf8f8:[function(){return n.e(892).then(n.bind(n,59488))},"@site/docs/Software/OpenBCISoftware/01-OpenBCI_GUI.md",59488],fd5221e6:[function(){return n.e(5417).then(n.bind(n,34622))},"@site/docs/Cyton/07-External_Trigger_Cyton_Example.md",34622],feddef67:[function(){return n.e(2734).then(n.bind(n,27879))},"@site/docs/Software/CompatibleThirdPartySoftware/06-BioEra.md",27879]};const d=function(e){var t={};return function e(n,r){Object.keys(n).forEach((function(a){var o,i=n[a],l=r?r+"."+a:a;"object"==typeof(o=i)&&o&&Object.keys(o).length>0?e(i,l):t[l]=i}))}(e),t};const f=function(e,t){if("*"===e)return l()({loading:s,loader:function(){return n.e(4608).then(n.bind(n,24608))}});var a=u[e+"-"+t],o=[],i=[],f={},p=d(a);return Object.keys(p).forEach((function(e){var t=c[p[e]];t&&(f[e]=t[0],o.push(t[1]),i.push(t[2]))})),l().Map({loading:s,loader:f,modules:o,webpack:function(){return i},render:function(e,t){var n=JSON.parse(JSON.stringify(a));Object.keys(e).forEach((function(t){for(var r=n,a=t.split("."),o=0;o1?t-1:0),r=1;r\n

    Your Docusaurus site did not load properly.

    \n

    A very common reason is a wrong site baseUrl configuration.

    \n

    Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'

    \n

    We suggest trying baseUrl =

    \n\n'}(e)).replace(/{"use strict";n.d(t,{Z:()=>l});var r=n(75068),a=n(67294),o=n(10412),i=n(14953);const l=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={error:null},n}(0,r.Z)(t,e);var n=t.prototype;return n.componentDidCatch=function(e){o.default.canUseDOM&&this.setState({error:e})},n.render=function(){var e,t=this,n=this.props.children,r=this.state.error;return r?(null!==(e=this.props.fallback)&&void 0!==e?e:i.Z)({error:r,tryAgain:function(){return t.setState({error:null})}}):n},t}(a.Component)},10412:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=!("undefined"==typeof window||!window.document||!window.document.createElement);const a={canUseDOM:r,canUseEventListeners:r&&!(!window.addEventListener&&!window.attachEvent),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&!!window.screen}},12859:(e,t,n)=>{"use strict";n.d(t,{Z:()=>me});var r,a,o,i,l=n(67294),s=n(45697),u=n.n(s),c=n(83524),d=n.n(c),f=n(69590),p=n.n(f),m=n(27418),h=n.n(m),g="bodyAttributes",b="htmlAttributes",v="titleAttributes",y={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title"},w=(Object.keys(y).map((function(e){return y[e]})),"charset"),E="cssText",S="href",k="http-equiv",x="innerHTML",C="itemprop",_="name",T="property",P="rel",A="src",D="target",L={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},O="defaultTitle",R="defer",N="encodeSpecialCharacters",F="onChangeClientState",I="titleTemplate",M=Object.keys(L).reduce((function(e,t){return e[L[t]]=t,e}),{}),G=[y.NOSCRIPT,y.SCRIPT,y.STYLE],B="data-react-helmet",j="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U=function(){function e(e,t){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n},Z=function(e){return!1===(!(arguments.length>1&&void 0!==arguments[1])||arguments[1])?String(e):String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},q=function(e){var t=K(e,y.TITLE),n=K(e,I);if(n&&t)return n.replace(/%s/g,(function(){return Array.isArray(t)?t.join(""):t}));var r=K(e,O);return t||r||void 0},$=function(e){return K(e,F)||function(){}},W=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return z({},e,t)}),{})},V=function(e,t){return t.filter((function(e){return void 0!==e[y.BASE]})).map((function(e){return e[y.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),a=0;a=0;n--){var r=e[n];if(r.hasOwnProperty(t))return r[t]}return null},Y=(r=Date.now(),function(e){var t=Date.now();t-r>16?(r=t,e(t)):setTimeout((function(){Y(e)}),0)}),X=function(e){return clearTimeout(e)},J="undefined"!=typeof window?window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||Y:n.g.requestAnimationFrame||Y,ee="undefined"!=typeof window?window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||X:n.g.cancelAnimationFrame||X,te=function(e){return console&&"function"==typeof console.warn&&console.warn(e)},ne=null,re=function(e,t){var n=e.baseTag,r=e.bodyAttributes,a=e.htmlAttributes,o=e.linkTags,i=e.metaTags,l=e.noscriptTags,s=e.onChangeClientState,u=e.scriptTags,c=e.styleTags,d=e.title,f=e.titleAttributes;ie(y.BODY,r),ie(y.HTML,a),oe(d,f);var p={baseTag:le(y.BASE,n),linkTags:le(y.LINK,o),metaTags:le(y.META,i),noscriptTags:le(y.NOSCRIPT,l),scriptTags:le(y.SCRIPT,u),styleTags:le(y.STYLE,c)},m={},h={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(m[e]=n),r.length&&(h[e]=p[e].oldTags)})),t&&t(),s(e,m,h)},ae=function(e){return Array.isArray(e)?e.join(""):e},oe=function(e,t){void 0!==e&&document.title!==e&&(document.title=ae(e)),ie(y.TITLE,t)},ie=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute(B),a=r?r.split(","):[],o=[].concat(a),i=Object.keys(t),l=0;l=0;d--)n.removeAttribute(o[d]);a.length===o.length?n.removeAttribute(B):n.getAttribute(B)!==i.join(",")&&n.setAttribute(B,i.join(","))}},le=function(e,t){var n=document.head||document.querySelector(y.HEAD),r=n.querySelectorAll(e+"["+B+"]"),a=Array.prototype.slice.call(r),o=[],i=void 0;return t&&t.length&&t.forEach((function(t){var n=document.createElement(e);for(var r in t)if(t.hasOwnProperty(r))if(r===x)n.innerHTML=t.innerHTML;else if(r===E)n.styleSheet?n.styleSheet.cssText=t.cssText:n.appendChild(document.createTextNode(t.cssText));else{var l=void 0===t[r]?"":t[r];n.setAttribute(r,l)}n.setAttribute(B,"true"),a.some((function(e,t){return i=t,n.isEqualNode(e)}))?a.splice(i,1):o.push(n)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),o.forEach((function(e){return n.appendChild(e)})),{oldTags:a,newTags:o}},se=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},ue=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[L[n]||n]=e[n],t}),t)},ce=function(e,t,n){switch(e){case y.TITLE:return{toComponent:function(){return e=t.title,n=t.titleAttributes,(r={key:e})[B]=!0,a=ue(n,r),[l.createElement(y.TITLE,a,e)];var e,n,r,a},toString:function(){return function(e,t,n,r){var a=se(n),o=ae(t);return a?"<"+e+" "+B+'="true" '+a+">"+Z(o,r)+"":"<"+e+" "+B+'="true">'+Z(o,r)+""}(e,t.title,t.titleAttributes,n)}};case g:case b:return{toComponent:function(){return ue(t)},toString:function(){return se(t)}};default:return{toComponent:function(){return function(e,t){return t.map((function(t,n){var r,a=((r={key:n})[B]=!0,r);return Object.keys(t).forEach((function(e){var n=L[e]||e;if(n===x||n===E){var r=t.innerHTML||t.cssText;a.dangerouslySetInnerHTML={__html:r}}else a[n]=t[e]})),l.createElement(e,a)}))}(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var a=Object.keys(r).filter((function(e){return!(e===x||e===E)})).reduce((function(e,t){var a=void 0===r[t]?t:t+'="'+Z(r[t],n)+'"';return e?e+" "+a:a}),""),o=r.innerHTML||r.cssText||"",i=-1===G.indexOf(e);return t+"<"+e+" "+B+'="true" '+a+(i?"/>":">"+o+"")}),"")}(e,t,n)}}}},de=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,a=e.htmlAttributes,o=e.linkTags,i=e.metaTags,l=e.noscriptTags,s=e.scriptTags,u=e.styleTags,c=e.title,d=void 0===c?"":c,f=e.titleAttributes;return{base:ce(y.BASE,t,r),bodyAttributes:ce(g,n,r),htmlAttributes:ce(b,a,r),link:ce(y.LINK,o,r),meta:ce(y.META,i,r),noscript:ce(y.NOSCRIPT,l,r),script:ce(y.SCRIPT,s,r),style:ce(y.STYLE,u,r),title:ce(y.TITLE,{title:d,titleAttributes:f},r)}},fe=d()((function(e){return{baseTag:V([S,D],e),bodyAttributes:W(g,e),defer:K(e,R),encode:K(e,N),htmlAttributes:W(b,e),linkTags:Q(y.LINK,[P,S],e),metaTags:Q(y.META,[_,w,k,T,C],e),noscriptTags:Q(y.NOSCRIPT,[x],e),onChangeClientState:$(e),scriptTags:Q(y.SCRIPT,[A,x],e),styleTags:Q(y.STYLE,[E],e),title:q(e),titleAttributes:W(v,e)}}),(function(e){ne&&ee(ne),e.defer?ne=J((function(){re(e,(function(){ne=null}))})):(re(e),ne=null)}),de)((function(){return null})),pe=(a=fe,i=o=function(e){function t(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}(this,e.apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.shouldComponentUpdate=function(e){return!p()(this.props,e)},t.prototype.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case y.SCRIPT:case y.NOSCRIPT:return{innerHTML:t};case y.STYLE:return{cssText:t}}throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")},t.prototype.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren,a=e.newChildProps,o=e.nestedChildren;return z({},r,((t={})[n.type]=[].concat(r[n.type]||[],[z({},a,this.mapNestedChildrenToProps(n,o))]),t))},t.prototype.mapObjectTypeChildren=function(e){var t,n,r=e.child,a=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(r.type){case y.TITLE:return z({},a,((t={})[r.type]=i,t.titleAttributes=z({},o),t));case y.BODY:return z({},a,{bodyAttributes:z({},o)});case y.HTML:return z({},a,{htmlAttributes:z({},o)})}return z({},a,((n={})[r.type]=z({},o),n))},t.prototype.mapArrayTypeChildrenToProps=function(e,t){var n=z({},t);return Object.keys(e).forEach((function(t){var r;n=z({},n,((r={})[t]=e[t],r))})),n},t.prototype.warnOnInvalidChildren=function(e,t){return!0},t.prototype.mapChildrenToProps=function(e,t){var n=this,r={};return l.Children.forEach(e,(function(e){if(e&&e.props){var a=e.props,o=a.children,i=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[M[n]||n]=e[n],t}),t)}(H(a,["children"]));switch(n.warnOnInvalidChildren(e,o),e.type){case y.LINK:case y.META:case y.NOSCRIPT:case y.SCRIPT:case y.STYLE:r=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:r,newChildProps:i,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:i,nestedChildren:o})}}})),t=this.mapArrayTypeChildrenToProps(r,t)},t.prototype.render=function(){var e=this.props,t=e.children,n=H(e,["children"]),r=z({},n);return t&&(r=this.mapChildrenToProps(t,r)),l.createElement(a,r)},U(t,null,[{key:"canUseDOM",set:function(e){a.canUseDOM=e}}]),t}(l.Component),o.propTypes={base:u().object,bodyAttributes:u().object,children:u().oneOfType([u().arrayOf(u().node),u().node]),defaultTitle:u().string,defer:u().bool,encodeSpecialCharacters:u().bool,htmlAttributes:u().object,link:u().arrayOf(u().object),meta:u().arrayOf(u().object),noscript:u().arrayOf(u().object),onChangeClientState:u().func,script:u().arrayOf(u().object),style:u().arrayOf(u().object),title:u().string,titleAttributes:u().object,titleTemplate:u().string},o.defaultProps={defer:!0,encodeSpecialCharacters:!0},o.peek=a.peek,o.rewind=function(){var e=a.rewind();return e||(e=de({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}})),e},i);pe.renderStatic=pe.rewind;const me=function(e){return l.createElement(pe,Object.assign({},e))}},39960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(63366),a=n(67294),o=n(73727),i=n(52263),l=n(13919),s=n(10412),u=(0,a.createContext)({collectLink:function(){}});var c=n(44996),d=n(18780),f=["isNavLink","to","href","activeClassName","isActive","data-noBrokenLinkCheck","autoAddBaseUrl"];const p=function(e){var t,n,p=e.isNavLink,m=e.to,h=e.href,g=e.activeClassName,b=e.isActive,v=e["data-noBrokenLinkCheck"],y=e.autoAddBaseUrl,w=void 0===y||y,E=(0,r.Z)(e,f),S=(0,i.Z)().siteConfig,k=S.trailingSlash,x=S.baseUrl,C=(0,c.C)().withBaseUrl,_=(0,a.useContext)(u),T=m||h,P=(0,l.Z)(T),A=null==T?void 0:T.replace("pathname://",""),D=void 0!==A?(n=A,w&&function(e){return e.startsWith("/")}(n)?C(n):n):void 0;D&&P&&(D=(0,d.applyTrailingSlash)(D,{trailingSlash:k,baseUrl:x}));var L=(0,a.useRef)(!1),O=p?o.OL:o.rU,R=s.default.canUseIntersectionObserver,N=(0,a.useRef)();(0,a.useEffect)((function(){return!R&&P&&null!=D&&window.docusaurus.prefetch(D),function(){R&&N.current&&N.current.disconnect()}}),[N,D,R,P]);var F=null!==(t=null==D?void 0:D.startsWith("#"))&&void 0!==t&&t,I=!D||!P||F;return D&&P&&!F&&!v&&_.collectLink(D),I?a.createElement("a",Object.assign({href:D},T&&!P&&{target:"_blank",rel:"noopener noreferrer"},E)):a.createElement(O,Object.assign({},E,{onMouseEnter:function(){L.current||null==D||(window.docusaurus.preload(D),L.current=!0)},innerRef:function(e){var t,n;R&&e&&P&&(t=e,n=function(){null!=D&&window.docusaurus.prefetch(D)},N.current=new window.IntersectionObserver((function(e){e.forEach((function(e){t===e.target&&(e.isIntersecting||e.intersectionRatio>0)&&(N.current.unobserve(t),N.current.disconnect(),n())}))})),N.current.observe(t))},to:D||""},p&&{isActive:b,activeClassName:g}))}},95999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>u});var r=n(67294),a=/{\w+}/g,o="{}";function i(e,t){var n=[],i=e.replace(a,(function(e){var a=e.substring(1,e.length-1),i=null==t?void 0:t[a];if(void 0!==i){var l=r.isValidElement(i)?i:String(i);return n.push(l),o}return e}));return 0===n.length?e:n.every((function(e){return"string"==typeof e}))?i.split(o).reduce((function(e,t,r){var a;return e.concat(t).concat(null!==(a=n[r])&&void 0!==a?a:"")}),""):i.split(o).reduce((function(e,t,a){return[].concat(e,[r.createElement(r.Fragment,{key:a},t,n[a])])}),[])}var l=n(57529);function s(e){var t,n,r=e.id,a=e.message;if(void 0===r&&void 0===a)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return null!==(n=null!==(t=l[null!=r?r:a])&&void 0!==t?t:a)&&void 0!==n?n:r}function u(e,t){return i(s({message:e.message,id:e.id}),t)}function c(e){var t=e.children,n=e.id,r=e.values;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");return i(s({message:t,id:n}),r)}},9913:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(67294),a=r.createContext(!1);function o(e){var t=e.children,n=(0,r.useState)(!1),o=n[0],i=n[1];return(0,r.useEffect)((function(){i(!0)}),[]),r.createElement(a.Provider,{value:o},t)}},29935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});var r="default"},50427:(e,t,n)=>{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(67294),a=n(99782),o=n(81115);const i=JSON.parse('{"defaultLocale":"en","locales":["en"],"currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr"}}}');var l=n(57529);const s=JSON.parse('{"docusaurusVersion":"2.0.0-beta.13","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.0.0-beta.13"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.0.0-beta.13"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.0.0-beta.13"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"2.0.0-beta.13"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.0.0-beta.13"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.0.0-beta.13"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.0.0-beta.13"}}}');var u={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},c=r.createContext(u);function d(e){var t=e.children;return r.createElement(c.Provider,{value:u},t)}},13919:(e,t,n)=>{"use strict";function r(e){return!0===/^(\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},46291:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=n(18790).H},28143:(e,t,n)=>{"use strict";n.r(t),n.d(t,{BrowserRouter:()=>r.VK,HashRouter:()=>r.UT,Link:()=>r.rU,MemoryRouter:()=>r.VA,NavLink:()=>r.OL,Prompt:()=>r.NL,Redirect:()=>r.l_,Route:()=>r.AW,Router:()=>r.F0,StaticRouter:()=>r.gx,Switch:()=>r.rs,generatePath:()=>r.Gn,matchPath:()=>r.LX,useHistory:()=>r.k6,useLocation:()=>r.TH,useParams:()=>r.UO,useRouteMatch:()=>r.$B,withRouter:()=>r.EN});var r=n(73727)},44996:(e,t,n)=>{"use strict";n.d(t,{C:()=>o,Z:()=>i});var r=n(52263),a=n(13919);function o(){var e=(0,r.Z)().siteConfig,t=void 0===e?{}:e,n=t.baseUrl,o=void 0===n?"/":n,i=t.url;return{withBaseUrl:function(e,t){return function(e,t,n,r){var o=void 0===r?{}:r,i=o.forcePrependBaseUrl,l=void 0!==i&&i,s=o.absolute,u=void 0!==s&&s;if(!n)return n;if(n.startsWith("#"))return n;if((0,a.b)(n))return n;if(l)return t+n;var c=n.startsWith(t)?n:t+n.replace(/^\//,"");return u?e+c:c}(i,o,e,t)}}}function i(e,t){return void 0===t&&(t={}),(0,o().withBaseUrl)(e,t)}},52263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(50427);const o=function(){return(0,r.useContext)(a._)}},28084:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o,useAllPluginInstancesData:()=>i,usePluginData:()=>l});var r=n(52263),a=n(29935);function o(){var e=(0,r.Z)().globalData;if(!e)throw new Error("Docusaurus global data not found.");return e}function i(e){var t=o()[e];if(!t)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin.');return t}function l(e,t){void 0===t&&(t=a.m);var n=i(e)[t];if(!n)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin with id "'+t+'".');return n}},72389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(9913);function o(){return(0,r.useContext)(a._)}},14953:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var r=n(67294),a=n(18882),o=n(20780);function i(e){var t=e.error,n=e.tryAgain;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",height:"50vh",width:"100%",fontSize:"20px"}},r.createElement("h1",null,"This page crashed."),r.createElement("p",null,t.message),r.createElement("button",{type:"button",onClick:n},"Try again"))}const l=function(e){var t=e.error,n=e.tryAgain;return r.createElement(o.Z,{fallback:function(){return r.createElement(i,{error:t,tryAgain:n})}},r.createElement(a.Z,{title:"Page Error"},r.createElement(i,{error:t,tryAgain:n})))}},48408:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getDocVersionSuggestions=t.getActiveDocContext=t.getActiveVersion=t.getLatestVersion=t.getActivePlugin=void 0;var r=n(28143);t.getActivePlugin=function(e,t,n){void 0===n&&(n={});var a=Object.entries(e).find((function(e){e[0];var n=e[1];return!!(0,r.matchPath)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error("Can't find active docs plugin for \""+t+'" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: '+Object.values(e).map((function(e){return e.path})).join(", "));return o};t.getLatestVersion=function(e){return e.versions.find((function(e){return e.isLast}))};t.getActiveVersion=function(e,n){var a=(0,t.getLatestVersion)(e);return[].concat(e.versions.filter((function(e){return e!==a})),[a]).find((function(e){return!!(0,r.matchPath)(n,{path:e.path,exact:!1,strict:!1})}))};t.getActiveDocContext=function(e,n){var a,o,i=(0,t.getActiveVersion)(e,n),l=null==i?void 0:i.docs.find((function(e){return!!(0,r.matchPath)(n,{path:e.path,exact:!0,strict:!1})}));return{activeVersion:i,activeDoc:l,alternateDocVersions:l?(a=l.id,o={},e.versions.forEach((function(e){e.docs.forEach((function(t){t.id===a&&(o[e.name]=t)}))})),o):{}}};t.getDocVersionSuggestions=function(e,n){var r=(0,t.getLatestVersion)(e),a=(0,t.getActiveDocContext)(e,n);return{latestDocSuggestion:null==a?void 0:a.alternateDocVersions[r.name],latestVersionSuggestion:r}}},96730:(e,t,n)=>{"use strict";t.Jo=t.Iw=t.zu=t.yW=t.gB=t.WS=t.gA=t.zh=t._r=void 0;var r=n(97582),a=n(28143),o=(0,r.__importStar)(n(28084)),i=n(48408),l={};t._r=function(){var e;return null!==(e=(0,o.default)()["docusaurus-plugin-content-docs"])&&void 0!==e?e:l};t.zh=function(e){return(0,o.usePluginData)("docusaurus-plugin-content-docs",e)};t.gA=function(e){void 0===e&&(e={});var n=(0,t._r)(),r=(0,a.useLocation)().pathname;return(0,i.getActivePlugin)(n,r,e)};t.WS=function(e){void 0===e&&(e={});var n=(0,t.gA)(e),r=(0,a.useLocation)().pathname;if(n)return{activePlugin:n,activeVersion:(0,i.getActiveVersion)(n.pluginData,r)}};t.gB=function(e){return(0,t.zh)(e).versions};t.yW=function(e){var n=(0,t.zh)(e);return(0,i.getLatestVersion)(n)};t.zu=function(e){var n=(0,t.zh)(e),r=(0,a.useLocation)().pathname;return(0,i.getActiveVersion)(n,r)};t.Iw=function(e){var n=(0,t.zh)(e),r=(0,a.useLocation)().pathname;return(0,i.getActiveDocContext)(n,r)};t.Jo=function(e){var n=(0,t.zh)(e),r=(0,a.useLocation)().pathname;return(0,i.getDocVersionSuggestions)(n,r)}},56657:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(97582),a=(0,r.__importDefault)(n(10412)),o=(0,r.__importDefault)(n(81115));t.default=function(){if(!a.default.canUseDOM)return null;var e=o.default["docusaurus-plugin-google-gtag"].default.trackingID;return{onRouteUpdate:function(t){var n=t.location;window.gtag("config",e,{page_path:n.pathname,page_title:document.title}),window.gtag("event","page_view",{page_title:document.title,page_location:n.href,page_path:n.pathname})}}}()},90541:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294);const a="iconExternalLink_wgqa";const o=function(e){var t=e.width,n=void 0===t?13.5:t,o=e.height,i=void 0===o?13.5:o;return r.createElement("svg",{width:n,height:i,"aria-hidden":"true",viewBox:"0 0 24 24",className:a},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},18882:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Ae});var r=n(67294),a=n(86010),o=n(20780),i=n(16550),l=n(95999),s=n(63616);const u="skipToContent_OuoZ";function c(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}const d=function(){var e=(0,r.useRef)(null),t=(0,i.k6)().action;return(0,s.SL)((function(n){var r=n.location;e.current&&!r.hash&&"PUSH"===t&&c(e.current)})),r.createElement("div",{ref:e},r.createElement("a",{href:"#",className:u,onClick:function(e){e.preventDefault();var t=document.querySelector("main:first-of-type")||document.querySelector(".main-wrapper");t&&c(t)}},r.createElement(l.Z,{id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"},"Skip to main content")))};var f=n(87462),p=n(63366),m=["width","height","color","strokeWidth","className"];function h(e){var t=e.width,n=void 0===t?21:t,a=e.height,o=void 0===a?21:a,i=e.color,l=void 0===i?"currentColor":i,s=e.strokeWidth,u=void 0===s?1.2:s,c=(e.className,(0,p.Z)(e,m));return r.createElement("svg",(0,f.Z)({viewBox:"0 0 15 15",width:n,height:o},c),r.createElement("g",{stroke:l,strokeWidth:u},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const g="announcementBar_axC9",b="announcementBarPlaceholder_xYHE",v="announcementBarClose_A3A1",y="announcementBarContent_6uhP";const w=function(){var e=(0,s.nT)(),t=e.isActive,n=e.close,o=(0,s.LU)().announcementBar;if(!t)return null;var i=o.content,u=o.backgroundColor,c=o.textColor,d=o.isCloseable;return r.createElement("div",{className:g,style:{backgroundColor:u,color:c},role:"banner"},d&&r.createElement("div",{className:b}),r.createElement("div",{className:y,dangerouslySetInnerHTML:{__html:i}}),d?r.createElement("button",{type:"button",className:(0,a.Z)("clean-btn close",v),onClick:n,"aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},r.createElement(h,{width:14,height:14,strokeWidth:3.1})):null)};var E=n(59166),S=n(72389);const k="toggle_iYfV",x="toggleScreenReader_h9qa",C="toggleDisabled_xj38",_="toggleTrack_t-f2",T="toggleTrackCheck_mk7D",P="toggleChecked_a04y",A="toggleTrackX_dm8H",D="toggleTrackThumb_W6To",L="toggleFocused_pRSw",O="toggleIcon_pHJ9";var R=(0,r.memo)((function(e){var t,n=e.className,o=e.switchConfig,i=e.checked,l=e.disabled,s=e.onChange,u=o.darkIcon,c=o.darkIconStyle,d=o.lightIcon,f=o.lightIconStyle,p=(0,r.useState)(i),m=p[0],h=p[1],g=(0,r.useState)(!1),b=g[0],v=g[1],y=(0,r.useRef)(null);return r.createElement("div",{className:(0,a.Z)(k,n,(t={},t[P]=m,t[L]=b,t[C]=l,t))},r.createElement("div",{className:_,role:"button",tabIndex:-1,onClick:function(){var e;return null==(e=y.current)?void 0:e.click()}},r.createElement("div",{className:T},r.createElement("span",{className:O,style:c},u)),r.createElement("div",{className:A},r.createElement("span",{className:O,style:f},d)),r.createElement("div",{className:D})),r.createElement("input",{ref:y,checked:m,type:"checkbox",className:x,"aria-label":"Switch between dark and light mode",onChange:s,onClick:function(){return h(!m)},onFocus:function(){return v(!0)},onBlur:function(){return v(!1)},onKeyDown:function(e){var t;"Enter"===e.key&&(null==(t=y.current)||t.click())}}))}));function N(e){var t=(0,s.LU)().colorMode.switchConfig,n=(0,S.Z)();return r.createElement(R,(0,f.Z)({switchConfig:t,disabled:!n},e))}var F=n(85350);const I=function(e){var t=(0,r.useState)(e),n=t[0],a=t[1],o=(0,r.useRef)(!1),i=(0,r.useRef)(0),l=(0,r.useCallback)((function(e){null!==e&&(i.current=e.getBoundingClientRect().height)}),[]);return(0,s.RF)((function(t,n){if(e){var r=t.scrollY;if(r=l?a(!1):r+u0&&r.createElement("button",{type:"button",className:"clean-btn navbar-sidebar__back",onClick:u.hide},r.createElement(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu")),u.content)))}const Q=function(){var e,t=(0,s.LU)().navbar,n=t.hideOnScroll,o=t.style,i=function(){var e=(0,G.Z)(),t="mobile"===e,n=(0,r.useState)(!1),a=n[0],o=n[1];(0,s.Rb)((function(){if(a)return o(!1),!1}));var i=(0,r.useCallback)((function(){o((function(e){return!e}))}),[]);return(0,r.useEffect)((function(){"desktop"===e&&o(!1)}),[e]),{shouldRender:t,toggle:i,shown:a}}(),l=W(),u=(0,B.gA)(),c=I(n),d=c.navbarRef,p=c.isNavbarVisible,m=$(),h=m.some((function(e){return"search"===e.type})),g=function(e){return{leftItems:e.filter((function(e){var t;return"left"===(null!=(t=e.position)?t:q)})),rightItems:e.filter((function(e){var t;return"right"===(null!=(t=e.position)?t:q)}))}}(m),b=g.leftItems,v=g.rightItems;return r.createElement("nav",{ref:d,className:(0,a.Z)("navbar","navbar--fixed-top",(e={"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown},e[Z.navbarHideable]=n,e[Z.navbarHidden]=n&&!p,e))},r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},((null==m?void 0:m.length)>0||u)&&r.createElement("button",{"aria-label":"Navigation bar toggle",className:"navbar__toggle clean-btn",type:"button",tabIndex:0,onClick:i.toggle,onKeyDown:i.toggle},r.createElement(H,null)),r.createElement(U.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title"}),b.map((function(e,t){return r.createElement(j.Z,(0,f.Z)({},e,{key:t}))}))),r.createElement("div",{className:"navbar__items navbar__items--right"},v.map((function(e,t){return r.createElement(j.Z,(0,f.Z)({},e,{key:t}))})),!l.disabled&&r.createElement(N,{className:Z.toggle,checked:l.isDarkTheme,onChange:l.toggle}),!h&&r.createElement(E.Z,null))),r.createElement("div",{role:"presentation",className:"navbar-sidebar__backdrop",onClick:i.toggle}),i.shouldRender&&r.createElement(V,{sidebarShown:i.shown,toggleSidebar:i.toggle}))};var K=n(39960),Y=n(44996),X=n(13919);const J="footerLogoLink_SRtH";var ee=n(89750),te=n(90541),ne=["to","href","label","prependBaseUrlToHref"];function re(e){var t=e.to,n=e.href,a=e.label,o=e.prependBaseUrlToHref,i=(0,p.Z)(e,ne),l=(0,Y.Z)(t),s=(0,Y.Z)(n,{forcePrependBaseUrl:!0});return r.createElement(K.Z,(0,f.Z)({className:"footer__link-item"},n?{href:o?s:n}:{to:l},i),n&&!(0,X.Z)(n)?r.createElement("span",null,a,r.createElement(te.Z,null)):a)}function ae(e){var t=e.sources,n=e.alt,a=e.width,o=e.height;return r.createElement(ee.Z,{className:"footer__logo",alt:n,sources:t,width:a,height:o})}const oe=function(){var e=(0,s.LU)().footer,t=e||{},n=t.copyright,o=t.links,i=void 0===o?[]:o,l=t.logo,u=void 0===l?{}:l,c={light:(0,Y.Z)(u.src),dark:(0,Y.Z)(u.srcDark||u.src)};return e?r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===e.style})},r.createElement("div",{className:"container"},i&&i.length>0&&r.createElement("div",{className:"row footer__links"},i.map((function(e,t){return r.createElement("div",{key:t,className:"col footer__col"},null!=e.title?r.createElement("div",{className:"footer__title"},e.title):null,null!=e.items&&Array.isArray(e.items)&&e.items.length>0?r.createElement("ul",{className:"footer__items"},e.items.map((function(e,t){return e.html?r.createElement("li",{key:t,className:"footer__item",dangerouslySetInnerHTML:{__html:e.html}}):r.createElement("li",{key:e.href||e.to,className:"footer__item"},r.createElement(re,e))}))):null)}))),(u||n)&&r.createElement("div",{className:"footer__bottom text--center"},u&&(u.src||u.srcDark)&&r.createElement("div",{className:"margin-bottom--sm"},u.href?r.createElement(K.Z,{href:u.href,className:J},r.createElement(ae,{alt:u.alt,sources:c,width:u.width,height:u.height})):r.createElement(ae,{alt:u.alt,sources:c})),n?r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:n}}):null))):null};var ie=n(10412),le=(0,s.WA)("theme"),se="light",ue="dark",ce=function(e){return e===ue?ue:se},de=function(e){(0,s.WA)("theme").set(ce(e))};const fe=function(){var e=(0,s.LU)().colorMode,t=e.defaultMode,n=e.disableSwitch,a=e.respectPrefersColorScheme,o=(0,r.useState)(function(e){return ie.default.canUseDOM?ce(document.documentElement.getAttribute("data-theme")):ce(e)}(t)),i=o[0],l=o[1],u=(0,r.useCallback)((function(){l(se),de(se)}),[]),c=(0,r.useCallback)((function(){l(ue),de(ue)}),[]);return(0,r.useEffect)((function(){document.documentElement.setAttribute("data-theme",ce(i))}),[i]),(0,r.useEffect)((function(){if(!n)try{var e=le.get();null!==e&&l(ce(e))}catch(t){console.error(t)}}),[n,l]),(0,r.useEffect)((function(){n&&!a||window.matchMedia("(prefers-color-scheme: dark)").addListener((function(e){var t=e.matches;l(t?ue:se)}))}),[n,a]),{isDarkTheme:i===ue,setLightTheme:u,setDarkTheme:c}};var pe=n(82924);const me=function(e){var t=fe(),n=t.isDarkTheme,a=t.setLightTheme,o=t.setDarkTheme,i=(0,r.useMemo)((function(){return{isDarkTheme:n,setLightTheme:a,setDarkTheme:o}}),[n,a,o]);return r.createElement(pe.Z.Provider,{value:i},e.children)};var he="docusaurus.tab.";const ge=function(){var e=(0,r.useState)({}),t=e[0],n=e[1],a=(0,r.useCallback)((function(e,t){(0,s.WA)(""+he+e).set(t)}),[]);return(0,r.useEffect)((function(){try{var e={};(0,s._f)().forEach((function(t){if(t.startsWith(he)){var n=t.substring(15);e[n]=(0,s.WA)(t).get()}})),n(e)}catch(t){console.error(t)}}),[]),{tabGroupChoices:t,setTabGroupChoices:function(e,t){n((function(n){var r;return Object.assign({},n,((r={})[e]=t,r))})),a(e,t)}}};const be=(0,r.createContext)(void 0);const ve=function(e){var t=ge(),n=t.tabGroupChoices,a=t.setTabGroupChoices,o=(0,r.useMemo)((function(){return{tabGroupChoices:n,setTabGroupChoices:a}}),[n,a]);return r.createElement(be.Provider,{value:o},e.children)};function ye(e){var t=e.children;return r.createElement(me,null,r.createElement(s.pl,null,r.createElement(ve,null,r.createElement(s.OC,null,r.createElement(s.L5,null,r.createElement(s.Cn,null,t))))))}var we=n(12859),Ee=n(52263);const Se=function(e){var t=e.locale,n=e.version,a=e.tag,o=t;return r.createElement(we.Z,null,o&&r.createElement("meta",{name:"docsearch:language",content:o}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),a&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:a}))};var ke=n(41217);function xe(){var e=(0,Ee.Z)().i18n,t=e.defaultLocale,n=e.locales,a=(0,s.l5)();return r.createElement(we.Z,null,n.map((function(e){return r.createElement("link",{key:e,rel:"alternate",href:a.createUrl({locale:e,fullyQualified:!0}),hrefLang:e})})),r.createElement("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}))}function Ce(e){var t=e.permalink,n=(0,Ee.Z)().siteConfig.url,a=function(){var e=(0,Ee.Z)().siteConfig.url,t=(0,i.TH)().pathname;return e+(0,Y.Z)(t)}(),o=t?""+n+t:a;return r.createElement(we.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function _e(e){var t=(0,Ee.Z)(),n=t.siteConfig.favicon,a=t.i18n,o=a.currentLocale,i=a.localeConfigs,l=(0,s.LU)(),u=l.metadata,c=l.image,d=e.title,p=e.description,m=e.image,h=e.keywords,g=e.searchMetadata,b=(0,Y.Z)(n),v=(0,s.pe)(d),y=o,w=i[o].direction;return r.createElement(r.Fragment,null,r.createElement(we.Z,null,r.createElement("html",{lang:y,dir:w}),n&&r.createElement("link",{rel:"icon",href:b}),r.createElement("title",null,v),r.createElement("meta",{property:"og:title",content:v}),r.createElement("meta",{name:"twitter:card",content:"summary_large_image"})),c&&r.createElement(ke.Z,{image:c}),m&&r.createElement(ke.Z,{image:m}),r.createElement(ke.Z,{description:p,keywords:h}),r.createElement(Ce,null),r.createElement(xe,null),r.createElement(Se,(0,f.Z)({tag:s.HX,locale:o},g)),r.createElement(we.Z,null,u.map((function(e,t){return r.createElement("meta",(0,f.Z)({key:"metadata_"+t},e))}))))}const Te=function(){(0,r.useEffect)((function(){var e="navigation-with-keyboard";function t(t){"keydown"===t.type&&"Tab"===t.key&&document.body.classList.add(e),"mousedown"===t.type&&document.body.classList.remove(e)}return document.addEventListener("keydown",t),document.addEventListener("mousedown",t),function(){document.body.classList.remove(e),document.removeEventListener("keydown",t),document.removeEventListener("mousedown",t)}}),[])};function Pe(e){var t=e.error,n=e.tryAgain;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},r.createElement(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again when the page crashed"},"Try again"))))))}const Ae=function(e){var t=e.children,n=e.noFooter,i=e.wrapperClassName,l=e.pageClassName;return Te(),r.createElement(ye,null,r.createElement(_e,e),r.createElement(d,null),r.createElement(w,null),r.createElement(Q,null),r.createElement("div",{className:(0,a.Z)(s.kM.wrapper.main,i,l)},r.createElement(o.Z,{fallback:Pe},t)),!n&&r.createElement(oe,null))}},55537:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(87462),a=n(63366),o=n(67294),i=n(39960),l=n(89750),s=n(44996),u=n(52263),c=n(63616),d=["imageClassName","titleClassName"];const f=function(e){var t=(0,u.Z)().siteConfig.title,n=(0,c.LU)().navbar,f=n.title,p=n.logo,m=void 0===p?{src:""}:p,h=e.imageClassName,g=e.titleClassName,b=(0,a.Z)(e,d),v=(0,s.Z)(m.href||"/"),y={light:(0,s.Z)(m.src),dark:(0,s.Z)(m.srcDark||m.src)},w=o.createElement(l.Z,{sources:y,height:m.height,width:m.width,alt:m.alt||f||t});return o.createElement(i.Z,(0,r.Z)({to:v},b,m.target&&{target:m.target}),m.src&&(h?o.createElement("div",{className:h},w):w),null!=f&&o.createElement("b",{className:g},f))}},5525:(e,t,n)=>{"use strict";n.d(t,{O:()=>v,Z:()=>E});var r=n(87462),a=n(63366),o=n(67294),i=n(86010),l=n(39960),s=n(44996),u=n(90541),c=n(13919),d=n(63616),f=n(42207),p=["activeBasePath","activeBaseRegex","to","href","label","activeClassName","prependBaseUrlToHref"],m=["className","isDropdownItem"],h=["className","isDropdownItem"],g=["mobile","position"],b="dropdown__link--active";function v(e){var t,n=e.activeBasePath,i=e.activeBaseRegex,f=e.to,m=e.href,h=e.label,g=e.activeClassName,v=void 0===g?"":g,y=e.prependBaseUrlToHref,w=(0,a.Z)(e,p),E=(0,s.Z)(f),S=(0,s.Z)(n),k=(0,s.Z)(m,{forcePrependBaseUrl:!0}),x=h&&m&&!(0,c.Z)(m),C=v===b;return o.createElement(l.Z,(0,r.Z)({},m?{href:y?k:m}:Object.assign({isNavLink:!0,activeClassName:null!=(t=w.className)&&t.includes(v)?"":v,to:E},n||i?{isActive:function(e,t){return i?(0,d.Fx)(i,t.pathname):t.pathname.startsWith(S)}}:null),w),x?o.createElement("span",null,h,o.createElement(u.Z,C&&{width:12,height:12})):h)}function y(e){var t=e.className,n=e.isDropdownItem,l=void 0!==n&&n,s=(0,a.Z)(e,m),u=o.createElement(v,(0,r.Z)({className:(0,i.Z)(l?"dropdown__link":"navbar__item navbar__link",t)},s));return l?o.createElement("li",null,u):u}function w(e){var t=e.className,n=(e.isDropdownItem,(0,a.Z)(e,h));return o.createElement("li",{className:"menu__list-item"},o.createElement(v,(0,r.Z)({className:(0,i.Z)("menu__link",t)},n)))}const E=function(e){var t,n=e.mobile,i=void 0!==n&&n,l=(e.position,(0,a.Z)(e,g)),s=i?w:y;return o.createElement(s,(0,r.Z)({},l,{activeClassName:null!=(t=l.activeClassName)?t:(0,f.E)(i)}))}},76400:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(87462),a=n(63366),o=n(67294),i=n(5525),l=n(80907),s=n(86010),u=n(42207),c=n(63616),d=["docId","label","docsPluginId"];function f(e){var t,n=e.docId,f=e.label,p=e.docsPluginId,m=(0,a.Z)(e,d),h=(0,l.Iw)(p),g=h.activeVersion,b=h.activeDoc,v=(0,c.J)(p).preferredVersion,y=(0,l.yW)(p),w=function(e,t){var n=e.flatMap((function(e){return e.docs})),r=n.find((function(e){return e.id===t}));if(!r){var a=n.map((function(e){return e.id})).join("\n- ");throw new Error("DocNavbarItem: couldn't find any doc with id \""+t+'" in version'+(e.length?"s":"")+" "+e.map((function(e){return e.name})).join(", ")+'".\nAvailable doc ids are:\n- '+a)}return r}((0,c.jj)([g,v,y].filter(Boolean)),n),E=(0,u.E)(m.mobile);return o.createElement(i.Z,(0,r.Z)({exact:!0},m,{className:(0,s.Z)(m.className,(t={},t[E]=(null==b?void 0:b.sidebar)&&b.sidebar===w.sidebar,t)),activeClassName:E,label:null!=f?f:w.id,to:w.path}))}},59308:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(87462),a=n(63366),o=n(67294),i=n(5525),l=n(23154),s=n(80907),u=n(63616),c=n(95999),d=["mobile","docsPluginId","dropdownActiveClassDisabled","dropdownItemsBefore","dropdownItemsAfter"],f=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};function p(e){var t,n,p=e.mobile,m=e.docsPluginId,h=e.dropdownActiveClassDisabled,g=e.dropdownItemsBefore,b=e.dropdownItemsAfter,v=(0,a.Z)(e,d),y=(0,s.Iw)(m),w=(0,s.gB)(m),E=(0,s.yW)(m),S=(0,u.J)(m),k=S.preferredVersion,x=S.savePreferredVersionName;var C,_=(C=w.map((function(e){var t=(null==y?void 0:y.alternateDocVersions[e.name])||f(e);return{isNavLink:!0,label:e.label,to:t.path,isActive:function(){return e===(null==y?void 0:y.activeVersion)},onClick:function(){x(e.name)}}})),[].concat(g,C,b)),T=null!=(t=null!=(n=y.activeVersion)?n:k)?t:E,P=p&&_?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):T.label,A=p&&_?void 0:f(T).path;return _.length<=1?o.createElement(i.Z,(0,r.Z)({},v,{mobile:p,label:P,to:A,isActive:h?function(){return!1}:void 0})):o.createElement(l.Z,(0,r.Z)({},v,{mobile:p,label:P,to:A,items:_,isActive:h?function(){return!1}:void 0}))}},47250:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(87462),a=n(63366),o=n(67294),i=n(5525),l=n(80907),s=n(63616),u=["label","to","docsPluginId"],c=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};function d(e){var t,n=e.label,d=e.to,f=e.docsPluginId,p=(0,a.Z)(e,u),m=(0,l.zu)(f),h=(0,s.J)(f).preferredVersion,g=(0,l.yW)(f),b=null!=(t=null!=m?m:h)?t:g,v=null!=n?n:b.label,y=null!=d?d:c(b).path;return o.createElement(i.Z,(0,r.Z)({},p,{label:v,to:y}))}},23154:(e,t,n)=>{"use strict";n.d(t,{Z:()=>b});var r=n(87462),a=n(63366),o=n(67294),i=n(86010),l=n(63616),s=n(5525),u=n(42207),c=["items","position","className"],d=["items","className","position"],f=["mobile"],p="dropdown__link--active";function m(e,t){return e.some((function(e){return function(e,t){return!!(0,l.Mg)(e.to,t)||!!(0,l.Fx)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)}))}function h(e){var t,n=e.items,l=e.position,d=e.className,f=(0,a.Z)(e,c),m=(0,o.useRef)(null),h=(0,o.useRef)(null),g=(0,o.useState)(!1),b=g[0],v=g[1];return(0,o.useEffect)((function(){var e=function(e){m.current&&!m.current.contains(e.target)&&v(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),function(){document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}}),[m]),o.createElement("div",{ref:m,className:(0,i.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===l,"dropdown--show":b})},o.createElement(s.O,(0,r.Z)({href:f.to?void 0:"#",className:(0,i.Z)("navbar__link",d)},f,{onClick:f.to?void 0:function(e){return e.preventDefault()},onKeyDown:function(e){"Enter"===e.key&&(e.preventDefault(),v(!b))}}),null!=(t=f.children)?t:f.label),o.createElement("ul",{ref:h,className:"dropdown__menu"},n.map((function(e,t){return o.createElement(u.Z,(0,r.Z)({isDropdownItem:!0,onKeyDown:function(e){if(t===n.length-1&&"Tab"===e.key){e.preventDefault(),v(!1);var r=m.current.nextElementSibling;r&&r.focus()}},activeClassName:p},e,{key:t}))}))))}function g(e){var t,n=e.items,c=e.className,f=(e.position,(0,a.Z)(e,d)),p=(0,l.be)(),h=m(n,p),g=(0,l.uR)({initialState:function(){return!h}}),b=g.collapsed,v=g.toggleCollapsed,y=g.setCollapsed;return(0,o.useEffect)((function(){h&&y(!h)}),[p,h,y]),o.createElement("li",{className:(0,i.Z)("menu__list-item",{"menu__list-item--collapsed":b})},o.createElement(s.O,(0,r.Z)({role:"button",className:(0,i.Z)("menu__link menu__link--sublist",c)},f,{onClick:function(e){e.preventDefault(),v()}}),null!=(t=f.children)?t:f.label),o.createElement(l.zF,{lazy:!0,as:"ul",className:"menu__list",collapsed:b},n.map((function(e,t){return o.createElement(u.Z,(0,r.Z)({mobile:!0,isDropdownItem:!0,onClick:f.onClick,activeClassName:"menu__link--active"},e,{key:t}))}))))}const b=function(e){var t=e.mobile,n=void 0!==t&&t,r=(0,a.Z)(e,f),i=n?g:h;return o.createElement(i,r)}},42207:(e,t,n)=>{"use strict";n.d(t,{Z:()=>E,E:()=>w});var r=n(63366),a=n(67294),o=n(5525),i=n(23154),l=n(87462),s=["width","height"];const u=function(e){var t=e.width,n=void 0===t?20:t,o=e.height,i=void 0===o?20:o,u=(0,r.Z)(e,s);return a.createElement("svg",(0,l.Z)({viewBox:"0 0 20 20",width:n,height:i,"aria-hidden":"true"},u),a.createElement("path",{fill:"currentColor",d:"M19.753 10.909c-.624-1.707-2.366-2.726-4.661-2.726-.09 0-.176.002-.262.006l-.016-2.063 3.525-.607c.115-.019.133-.119.109-.231-.023-.111-.167-.883-.188-.976-.027-.131-.102-.127-.207-.109-.104.018-3.25.461-3.25.461l-.013-2.078c-.001-.125-.069-.158-.194-.156l-1.025.016c-.105.002-.164.049-.162.148l.033 2.307s-3.061.527-3.144.543c-.084.014-.17.053-.151.143.019.09.19 1.094.208 1.172.018.08.072.129.188.107l2.924-.504.035 2.018c-1.077.281-1.801.824-2.256 1.303-.768.807-1.207 1.887-1.207 2.963 0 1.586.971 2.529 2.328 2.695 3.162.387 5.119-3.06 5.769-4.715 1.097 1.506.256 4.354-2.094 5.98-.043.029-.098.129-.033.207l.619.756c.08.096.206.059.256.023 2.51-1.73 3.661-4.515 2.869-6.683zm-7.386 3.188c-.966-.121-.944-.914-.944-1.453 0-.773.327-1.58.876-2.156a3.21 3.21 0 011.229-.799l.082 4.277a2.773 2.773 0 01-1.243.131zm2.427-.553l.046-4.109c.084-.004.166-.01.252-.01.773 0 1.494.145 1.885.361.391.217-1.023 2.713-2.183 3.758zm-8.95-7.668a.196.196 0 00-.196-.145h-1.95a.194.194 0 00-.194.144L.008 16.916c-.017.051-.011.076.062.076h1.733c.075 0 .099-.023.114-.072l1.008-3.318h3.496l1.008 3.318c.016.049.039.072.113.072h1.734c.072 0 .078-.025.062-.076-.014-.05-3.083-9.741-3.494-11.04zm-2.618 6.318l1.447-5.25 1.447 5.25H3.226z"}))};var c=n(52263),d=n(63616);const f="iconLanguage_EbrZ";var p=["mobile","dropdownItemsBefore","dropdownItemsAfter"];function m(e){var t=e.mobile,n=e.dropdownItemsBefore,o=e.dropdownItemsAfter,s=(0,r.Z)(e,p),m=(0,c.Z)().i18n,h=m.currentLocale,g=m.locales,b=m.localeConfigs,v=(0,d.l5)();function y(e){return b[e].label}var w=g.map((function(e){var t="pathname://"+v.createUrl({locale:e,fullyQualified:!1});return{isNavLink:!0,label:y(e),to:t,target:"_self",autoAddBaseUrl:!1,className:e===h?"dropdown__link--active":""}})),E=[].concat(n,w,o),S=t?"Languages":y(h);return a.createElement(i.Z,(0,l.Z)({},s,{mobile:t,label:a.createElement("span",null,a.createElement(u,{className:f}),a.createElement("span",null,S)),items:E}))}var h=n(59166);function g(e){return e.mobile?null:a.createElement(h.Z,null)}var b=["type"],v={default:function(){return o.Z},localeDropdown:function(){return m},search:function(){return g},dropdown:function(){return i.Z},docsVersion:function(){return n(47250).Z},docsVersionDropdown:function(){return n(59308).Z},doc:function(){return n(76400).Z}},y=function(e){var t=v[e];if(!t)throw new Error('No NavbarItem component found for type "'+e+'".');return t()};var w=function(e){return e?"menu__link--active":"navbar__link--active"};function E(e){var t=e.type,n=(0,r.Z)(e,b),o=function(e,t){return e&&"default"!==e?e:t?"dropdown":"default"}(t,void 0!==n.items),i=y(o);return a.createElement(i,n)}},41217:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var r=n(67294),a=n(12859),o=n(63616),i=n(44996);function l(e){var t=e.title,n=e.description,l=e.keywords,s=e.image,u=e.children,c=(0,o.pe)(t),d=(0,i.C)().withBaseUrl,f=s?d(s,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),l&&r.createElement("meta",{name:"keywords",content:Array.isArray(l)?l.join(","):l}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),u)}},82924:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=n(67294).createContext(void 0)},89750:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(87462),a=n(63366),o=n(67294),i=n(86010),l=n(72389),s=n(85350);const u={themedImage:"themedImage_TMUO","themedImage--light":"themedImage--light_4Vu1","themedImage--dark":"themedImage--dark_uzRr"};var c=["sources","className","alt"];const d=function(e){var t=(0,l.Z)(),n=(0,s.Z)().isDarkTheme,d=e.sources,f=e.className,p=e.alt,m=void 0===p?"":p,h=(0,a.Z)(e,c),g=t?n?["dark"]:["light"]:["light","dark"];return o.createElement(o.Fragment,null,g.map((function(e){return o.createElement("img",(0,r.Z)({key:e,src:d[e],alt:m,className:(0,i.Z)(u.themedImage,u["themedImage--"+e],f)},h))})))}},80907:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>r.Iw,Jo:()=>r.Jo,WS:()=>r.WS,_r:()=>r._r,gA:()=>r.gA,gB:()=>r.gB,yW:()=>r.yW,zh:()=>r.zh,zu:()=>r.zu});var r=n(96730)},85350:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294),a=n(82924);const o=function(){var e=(0,r.useContext)(a.Z);if(null==e)throw new Error('"useThemeContext" is used outside of "Layout" component. Please see https://docusaurus.io/docs/api/themes/configuration#usethemecontext.');return e}},93783:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(67294),a=n(10412),o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.default.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=function(){var e=(0,r.useState)((function(){return l()})),t=e[0],n=e[1];return(0,r.useEffect)((function(){function e(){n(l())}return window.addEventListener("resize",e),function(){window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),t}},40467:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(10412),a=n(99782);const o=function(e){if(r.default.canUseDOM){var t=a.default.themeConfig.prism,o=(void 0===t?{}:t).additionalLanguages,i=void 0===o?[]:o;window.Prism=e,i.forEach((function(e){n(6726)("./prism-"+e)})),delete window.Prism}}},72448:(e,t,n)=>{"use strict";var r=a(n(87410));function a(e){return e&&e.__esModule?e:{default:e}}(0,a(n(40467)).default)(r.default)},63616:(e,t,n)=>{"use strict";n.d(t,{pl:()=>$e,zF:()=>ke,HX:()=>B,PO:()=>Oe,L5:()=>R,bT:()=>x,qu:()=>E,Cv:()=>Me,Cn:()=>Ne,OC:()=>rt,kM:()=>Be,WA:()=>u,os:()=>j,Wl:()=>_,_F:()=>T,Fx:()=>lt,Mg:()=>b,_f:()=>c,bc:()=>Y,Vo:()=>X,nZ:()=>J,jj:()=>Ge,l5:()=>f,nT:()=>We,uR:()=>he,_q:()=>U,J:()=>M,Vq:()=>C,E6:()=>S,ed:()=>le,Rb:()=>Qe,be:()=>Ve,SL:()=>ue,g8:()=>Ie,c2:()=>oe,D9:()=>se,RF:()=>it,DA:()=>tt,Si:()=>Je,LU:()=>a,pe:()=>ee});var r=n(52263);function a(){return(0,r.Z)().siteConfig.themeConfig}var o="localStorage";function i(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}var l=!1;var s={get:function(){return null},set:function(){},del:function(){}};var u=function(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error('Illegal storage API usage for storage key "'+e+'".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.')}return{get:t,set:t,del:t}}(e);var n=i(null==t?void 0:t.persistence);return null===n?s:{get:function(){try{return n.getItem(e)}catch(t){return console.error("Docusaurus storage error, can't get key="+e,t),null}},set:function(t){try{n.setItem(e,t)}catch(r){console.error("Docusaurus storage error, can't set "+e+"="+t,r)}},del:function(){try{n.removeItem(e)}catch(t){console.error("Docusaurus storage error, can't delete key="+e,t)}}}};function c(e){void 0===e&&(e=o);var t=i(e);if(!t)return[];for(var n=[],r=0;re.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var b=function(e,t){var n=function(e){return!e||(null==e?void 0:e.endsWith("/"))?e:e+"/"};return n(e)===n(t)},v=!!p._r,y=Symbol("EmptyContext"),w=(0,m.createContext)(y);function E(e){var t=e.children,n=e.version;return m.createElement(w.Provider,{value:n},t)}function S(){var e=(0,m.useContext)(w);if(e===y)throw new Error("This hook requires usage of ");return e}var k=(0,m.createContext)(y);function x(e){var t=e.children,n=e.sidebar;return m.createElement(k.Provider,{value:n},t)}function C(){var e=(0,m.useContext)(k);if(e===y)throw new Error("This hook requires usage of ");return e}function _(e){if(e.href)return e.href;for(var t,n=g(e.items);!(t=n()).done;){var r=t.value;if("link"===r.type)return r.href;if("category"!==r.type)throw new Error("Unexpected category item type for "+JSON.stringify(r));var a=_(r);if(a)return a}}function T(e,t){var n=function(e){return void 0!==e&&b(e,t)};return"link"===e.type?n(e.href):"category"===e.type&&(n(e.href)||function(e,t){return e.some((function(e){return T(e,t)}))}(e.items,t))}var P=function(e){return"docs-preferred-version-"+e};const A={save:function(e,t,n){u(P(e),{persistence:t}).set(n)},read:function(e,t){return u(P(e),{persistence:t}).get()},clear:function(e,t){u(P(e),{persistence:t}).del()}};function D(e){var t=e.pluginIds,n=e.versionPersistence,r=e.allDocsData;var a={};return t.forEach((function(e){a[e]=function(e){var t=A.read(e,n);return r[e].versions.some((function(e){return e.name===t}))?{preferredVersionName:t}:(A.clear(e,n),{preferredVersionName:null})}(e)})),a}function L(){var e=(0,p._r)(),t=a().docs.versionPersistence,n=(0,m.useMemo)((function(){return Object.keys(e)}),[e]),r=(0,m.useState)((function(){return function(e){var t={};return e.forEach((function(e){t[e]={preferredVersionName:null}})),t}(n)})),o=r[0],i=r[1];return(0,m.useEffect)((function(){i(D({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]),[o,(0,m.useMemo)((function(){return{savePreferredVersion:function(e,n){A.save(e,t,n),i((function(t){var r;return Object.assign({},t,((r={})[e]={preferredVersionName:n},r))}))}}}),[t])]}var O=(0,m.createContext)(null);function R(e){var t=e.children;return v?m.createElement(N,null,t):t}function N(e){var t=e.children,n=L();return m.createElement(O.Provider,{value:n},t)}function F(){var e=(0,m.useContext)(O);if(!e)throw new Error('Can\'t find docs preferred context, maybe you forgot to use the "DocsPreferredVersionContextProvider"?');return e}var I=n(29935);function M(e){void 0===e&&(e=I.m);var t=(0,p.zh)(e),n=F(),r=n[0],a=n[1],o=r[e].preferredVersionName;return{preferredVersion:o?t.versions.find((function(e){return e.name===o})):null,savePreferredVersionName:(0,m.useCallback)((function(t){a.savePreferredVersion(e,t)}),[a,e])}}function G(){var e=(0,p._r)(),t=F()[0];var n=Object.keys(e),r={};return n.forEach((function(n){r[n]=function(n){var r=e[n],a=t[n].preferredVersionName;return a?r.versions.find((function(e){return e.name===a})):null}(n)})),r}var B="default";function j(e,t){return"docs-"+e+"-"+t}function U(){var e=(0,r.Z)().i18n,t=(0,p._r)(),n=(0,p.WS)(),a=G();var o=[B].concat(Object.keys(t).map((function(e){var r,o,i=(null===(r=null==n?void 0:n.activePlugin)||void 0===r?void 0:r.pluginId)===e?n.activeVersion:void 0,l=a[e],s=t[e].versions.find((function(e){return e.isLast}));return j(e,(null!==(o=null!=i?i:l)&&void 0!==o?o:s).name)})));return{locale:e.currentLocale,tags:o}}var z=n(87594),H=n.n(z),Z=/title=(["'])(.*?)\1/,q=/{([\d,-]+)}/,$=["js","jsBlock","jsx","python","html"],W={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},python:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},V=["highlight-next-line","highlight-start","highlight-end"],Q=function(e){void 0===e&&(e=$);var t=e.map((function(e){var t=W[e],n=t.start,r=t.end;return"(?:"+n+"\\s*("+V.join("|")+")\\s*"+r+")"})).join("|");return new RegExp("^\\s*(?:"+t+")\\s*$")},K=function(e){switch(e){case"js":case"javascript":case"ts":case"typescript":return Q(["js","jsBlock"]);case"jsx":case"tsx":return Q(["js","jsBlock","jsx"]);case"html":return Q(["js","jsBlock","html"]);case"python":case"py":return Q(["python"]);default:return Q()}};function Y(e){var t,n;return null!==(n=null===(t=null==e?void 0:e.match(Z))||void 0===t?void 0:t[2])&&void 0!==n?n:""}function X(e){var t=null==e?void 0:e.split(" ").find((function(e){return e.startsWith("language-")}));return null==t?void 0:t.replace(/language-/,"")}function J(e,t,n){var r=e.replace(/\n$/,"");if(t&&q.test(t)){var a=t.match(q)[1];return{highlightLines:H()(a).filter((function(e){return e>0})).map((function(e){return e-1})),code:r}}if(void 0===n)return{highlightLines:[],code:r};for(var o,i=K(n),l=r.split("\n"),s="",u=0;un.pluralForms.length&&console.error("For locale="+n.locale+", a maximum of "+n.pluralForms.length+" plural forms are expected ("+n.pluralForms+"), but the message contains "+r.length+" plural forms: "+e+" ");var a=n.select(t),o=n.pluralForms.indexOf(a);return r[Math.min(o,r.length-1)]}(n,t,e)}}}var ie="undefined"!=typeof window?m.useLayoutEffect:m.useEffect;function le(e){var t=(0,m.useRef)(e);return ie((function(){t.current=e}),[e]),(0,m.useCallback)((function(){return t.current.apply(t,arguments)}),[])}function se(e){var t=(0,m.useRef)();return ie((function(){t.current=e})),t.current}function ue(e){var t=(0,d.TH)(),n=se(t),r=le(e);(0,m.useEffect)((function(){t!==n&&r({location:t,previousLocation:n})}),[r,t,n])}var ce=n(63366),de=n(10412),fe=["collapsed"],pe=["lazy"],me="ease-in-out";function he(e){var t=e.initialState,n=(0,m.useState)(null!=t&&t),r=n[0],a=n[1],o=(0,m.useCallback)((function(){a((function(e){return!e}))}),[]);return{collapsed:r,setCollapsed:a,toggleCollapsed:o}}var ge={display:"none",overflow:"hidden",height:"0px"},be={display:"block",overflow:"visible",height:"auto"};function ve(e,t){var n=t?ge:be;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function ye(e){var t=e.collapsibleRef,n=e.collapsed,r=e.animation,a=(0,m.useRef)(!1);(0,m.useEffect)((function(){var e,o=t.current;function i(){var e,t,n=o.scrollHeight,a=null!==(e=null==r?void 0:r.duration)&&void 0!==e?e:function(e){var t=e/36;return Math.round(10*(4+15*Math.pow(t,.25)+t/5))}(n);return{transition:"height "+a+"ms "+(null!==(t=null==r?void 0:r.easing)&&void 0!==t?t:me),height:n+"px"}}function l(){var e=i();o.style.transition=e.transition,o.style.height=e.height}if(!a.current)return ve(o,n),void(a.current=!0);return o.style.willChange="height",e=requestAnimationFrame((function(){n?(l(),requestAnimationFrame((function(){o.style.height=ge.height,o.style.overflow=ge.overflow}))):(o.style.display="block",requestAnimationFrame((function(){l()})))})),function(){return cancelAnimationFrame(e)}}),[t,n,r])}function we(e){if(!de.default.canUseDOM)return e?ge:be}function Ee(e){var t=e.as,n=void 0===t?"div":t,r=e.collapsed,a=e.children,o=e.animation,i=e.onCollapseTransitionEnd,l=e.className,s=e.disableSSRStyle,u=(0,m.useRef)(null);return ye({collapsibleRef:u,collapsed:r,animation:o}),m.createElement(n,{ref:u,style:s?void 0:we(r),onTransitionEnd:function(e){"height"===e.propertyName&&(ve(u.current,r),null==i||i(r))},className:l},a)}function Se(e){var t=e.collapsed,n=(0,ce.Z)(e,fe),r=(0,m.useState)(!t),a=r[0],o=r[1];(0,m.useLayoutEffect)((function(){t||o(!0)}),[t]);var i=(0,m.useState)(t),l=i[0],s=i[1];return(0,m.useLayoutEffect)((function(){a&&s(t)}),[a,t]),a?m.createElement(Ee,Object.assign({},n,{collapsed:l})):null}function ke(e){var t=e.lazy,n=(0,ce.Z)(e,pe),r=t?Se:Ee;return m.createElement(r,Object.assign({},n))}var xe=n(72389),Ce=n(86010);const _e="details_Q743",Te="isBrowser_rWTL",Pe="collapsibleContent_K5uX";var Ae=["summary","children"];function De(e){return!!e&&("SUMMARY"===e.tagName||De(e.parentElement))}function Le(e,t){return!!e&&(e===t||Le(e.parentElement,t))}const Oe=function(e){var t,n=e.summary,r=e.children,a=(0,ce.Z)(e,Ae),o=(0,xe.Z)(),i=(0,m.useRef)(null),l=he({initialState:!a.open}),s=l.collapsed,u=l.setCollapsed,c=(0,m.useState)(a.open),d=c[0],f=c[1];return m.createElement("details",Object.assign({},a,{ref:i,open:d,"data-collapsed":s,className:(0,Ce.Z)(_e,(t={},t[Te]=o,t),a.className),onMouseDown:function(e){De(e.target)&&e.detail>1&&e.preventDefault()},onClick:function(e){e.stopPropagation();var t=e.target;De(t)&&Le(t,i.current)&&(e.preventDefault(),s?(u(!1),f(!0)):u(!0))}}),n,m.createElement(ke,{lazy:!1,collapsed:s,disableSSRStyle:!0,onCollapseTransitionEnd:function(e){u(e),f(!e)}},m.createElement("div",{className:Pe},r)))};var Re=(0,m.createContext)(null);function Ne(e){var t=e.children;return m.createElement(Re.Provider,{value:(0,m.useState)(null)},t)}function Fe(){var e=(0,m.useContext)(Re);if(null===e)throw new Error("MobileSecondaryMenuProvider was not used correctly, context value is null");return e}function Ie(){var e=Fe()[0];if(e){var t=e.component;return function(n){return m.createElement(t,Object.assign({},e.props,n))}}return function(){}}function Me(e){var t,n=e.component,r=e.props,a=Fe()[1],o=(t=r,(0,m.useMemo)((function(){return t}),[].concat(Object.keys(t),Object.values(t))));return(0,m.useEffect)((function(){a({component:n,props:o})}),[a,n,o]),(0,m.useEffect)((function(){return function(){return a(null)}}),[a]),null}function Ge(e){return Array.from(new Set(e))}var Be={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button"},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:function(e){return"theme-doc-sidebar-item-category-level-"+e},docSidebarItemLinkLevel:function(e){return"theme-doc-sidebar-item-link-level-"+e}},blog:{}},je=u("docusaurus.announcement.dismiss"),Ue=u("docusaurus.announcement.id"),ze=function(){return"true"===je.get()},He=function(e){return je.set(String(e))},Ze=function(){var e=a().announcementBar,t=(0,xe.Z)(),n=(0,m.useState)((function(){return!!t&&ze()})),r=n[0],o=n[1];(0,m.useEffect)((function(){o(ze())}),[]);var i=(0,m.useCallback)((function(){He(!0),o(!0)}),[]);return(0,m.useEffect)((function(){if(e){var t=e.id,n=Ue.get();"annoucement-bar"===n&&(n="announcement-bar");var r=t!==n;Ue.set(t),r&&He(!1),!r&&ze()||o(!1)}}),[e]),(0,m.useMemo)((function(){return{isActive:!!e&&!r,close:i}}),[e,r,i])},qe=(0,m.createContext)(null);function $e(e){var t=e.children,n=Ze();return m.createElement(qe.Provider,{value:n},t)}var We=function(){var e=(0,m.useContext)(qe);if(!e)throw new Error("useAnnouncementBar(): AnnouncementBar not found in React context: make sure to use the AnnouncementBarProvider on top of the tree");return e};function Ve(){var e=(0,r.Z)().siteConfig.baseUrl;return(0,d.TH)().pathname.replace(e,"/")}n(95999);function Qe(e){!function(e){var t=(0,d.k6)().block,n=(0,m.useRef)(e);(0,m.useEffect)((function(){n.current=e}),[e]),(0,m.useEffect)((function(){return t((function(e,t){return n.current(e,t)}))}),[t,n])}((function(t,n){if("POP"===n)return e(t,n)}))}function Ke(e){var t=e.getBoundingClientRect();return t.top===t.bottom?Ke(e.parentNode):t}function Ye(e,t){var n,r=t.anchorTopOffset,a=e.find((function(e){return Ke(e).top>=r}));return a?function(e){return e.top>0&&e.bottom=n&&e.level<=r}(e)?[Object.assign({},e,{children:t})]:t}))}function tt(e){var t=e.toc,n=e.minHeadingLevel,r=e.maxHeadingLevel;return(0,m.useMemo)((function(){return et({toc:t,minHeadingLevel:n,maxHeadingLevel:r})}),[t,n,r])}var nt=(0,m.createContext)(void 0);function rt(e){var t,n=e.children;return m.createElement(nt.Provider,{value:(t=(0,m.useRef)(!0),(0,m.useMemo)((function(){return{scrollEventsEnabledRef:t,enableScrollEvents:function(){t.current=!0},disableScrollEvents:function(){t.current=!1}}}),[]))},n)}function at(){var e=(0,m.useContext)(nt);if(null==e)throw new Error('"useScrollController" is used but no context provider was found in the React tree.');return e}var ot=function(){return de.default.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null};function it(e,t){void 0===t&&(t=[]);var n=at().scrollEventsEnabledRef,r=(0,m.useRef)(ot()),a=le(e);(0,m.useEffect)((function(){var e=function(){if(n.current){var e=ot();a&&a(e,r.current),r.current=e}},t={passive:!0};return e(),window.addEventListener("scroll",e,t),function(){return window.removeEventListener("scroll",e,t)}}),[a,n].concat(t))}function lt(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}},59166:(e,t,n)=>{"use strict";n.d(t,{Z:()=>D});var r=n(87462),a=n(63366),o=n(67294),i=n(73935),l=n(52263),s=n(16550),u=n(44996),c=n(39960),d=n(12859),f=n(99565),p=n(63616);function m(){return o.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},o.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var h=n(20830),g=["translations"];function b(){return b=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var E="Ctrl";var S=o.forwardRef((function(e,t){var n=e.translations,r=void 0===n?{}:n,a=w(e,g),i=r.buttonText,l=void 0===i?"Search":i,s=r.buttonAriaLabel,u=void 0===s?"Search":s,c=v((0,o.useState)(null),2),d=c[0],f=c[1];return(0,o.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?f("\u2318"):f(E))}),[]),o.createElement("button",b({type:"button",className:"DocSearch DocSearch-Button","aria-label":u},a,{ref:t}),o.createElement("span",{className:"DocSearch-Button-Container"},o.createElement(h.W,null),o.createElement("span",{className:"DocSearch-Button-Placeholder"},l)),o.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&o.createElement(o.Fragment,null,o.createElement("kbd",{className:"DocSearch-Button-Key"},d===E?o.createElement(m,null):d),o.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))}));var k=n(95999);const x={searchBox:"searchBox_Utm0"};var C=["contextualSearch","externalUrlRegex"],_=null;function T(e){var t=e.hit,n=e.children;return o.createElement(c.Z,{to:t.url},n)}function P(e){var t=e.state,n=e.onClose,r=(0,f.Z)().generateSearchPageLink;return o.createElement(c.Z,{to:r(t.query),onClick:n},"See all ",t.context.nbHits," results")}function A(e){var t,c,f,m=e.contextualSearch,h=e.externalUrlRegex,g=(0,a.Z)(e,C),b=(0,l.Z)().siteMetadata,v=["language:"+(f=(0,p._q)()).locale,f.tags.map((function(e){return"docusaurus_tag:"+e}))],y=null!==(c=null===(t=g.searchParameters)||void 0===t?void 0:t.facetFilters)&&void 0!==c?c:[],w=m?[].concat(v,y):y,E=Object.assign({},g.searchParameters,{facetFilters:w}),A=(0,u.C)().withBaseUrl,D=(0,s.k6)(),L=(0,o.useRef)(null),O=(0,o.useRef)(null),R=(0,o.useState)(!1),N=R[0],F=R[1],I=(0,o.useState)(void 0),M=I[0],G=I[1],B=(0,o.useCallback)((function(){return _?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,61426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,46945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,18894))]).then((function(e){var t=e[0].DocSearchModal;_=t}))}),[]),j=(0,o.useCallback)((function(){B().then((function(){L.current=document.createElement("div"),document.body.insertBefore(L.current,document.body.firstChild),F(!0)}))}),[B,F]),U=(0,o.useCallback)((function(){var e;F(!1),null===(e=L.current)||void 0===e||e.remove()}),[F]),z=(0,o.useCallback)((function(e){B().then((function(){F(!0),G(e.key)}))}),[B,F,G]),H=(0,o.useRef)({navigate:function(e){var t=e.itemUrl;(0,p.Fx)(h,t)?window.location.href=t:D.push(t)}}).current,Z=(0,o.useRef)((function(e){return e.map((function(e){if((0,p.Fx)(h,e.url))return e;var t=new URL(e.url);return Object.assign({},e,{url:A(""+t.pathname+t.hash)})}))})).current,q=(0,o.useMemo)((function(){return function(e){return o.createElement(P,(0,r.Z)({},e,{onClose:U}))}}),[U]),$=(0,o.useCallback)((function(e){return e.addAlgoliaAgent("docusaurus",b.docusaurusVersion),e}),[b.docusaurusVersion]);!function(e){var t=e.isOpen,n=e.onOpen,r=e.onClose,a=e.onInput,i=e.searchButtonRef;o.useEffect((function(){function e(e){var o;(27===e.keyCode&&t||"k"===(null===(o=e.key)||void 0===o?void 0:o.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?r():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&a&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&a(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,r,a,i])}({isOpen:N,onOpen:j,onClose:U,onInput:z,searchButtonRef:O});var W=(0,k.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"});return o.createElement(o.Fragment,null,o.createElement(d.Z,null,o.createElement("link",{rel:"preconnect",href:"https://"+g.appId+"-dsn.algolia.net",crossOrigin:"anonymous"})),o.createElement("div",{className:x.searchBox},o.createElement(S,{onTouchStart:B,onFocus:B,onMouseOver:B,onClick:j,ref:O,translations:{buttonText:W,buttonAriaLabel:W}})),N&&_&&L.current&&(0,i.createPortal)(o.createElement(_,(0,r.Z)({onClose:U,initialScrollY:window.scrollY,initialQuery:M,navigator:H,transformItems:Z,hitComponent:T,resultsFooterComponent:q,transformSearchClient:$},g,{searchParameters:E})),L.current))}const D=function(){var e=(0,l.Z)().siteConfig;return o.createElement(A,e.themeConfig.algolia)}},99565:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(16550),a=n(52263),o=n(67294);const i=function(){var e=(0,r.k6)(),t=(0,a.Z)().siteConfig.baseUrl,n=(0,o.useState)(""),i=n[0],l=n[1];return(0,o.useEffect)((function(){var e,t=null!==(e=new URLSearchParams(window.location.search).get("q"))&&void 0!==e?e:"";l(t)}),[]),{searchQuery:i,setSearchQuery:(0,o.useCallback)((function(t){var n=new URLSearchParams(window.location.search);t?n.set("q",t):n.delete("q"),e.replace({search:n.toString()}),l(t)}),[e]),generateSearchPageLink:(0,o.useCallback)((function(e){return t+"search?q="+encodeURIComponent(e)}),[t])}}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n=t.trailingSlash,r=t.baseUrl;if(e.startsWith("#"))return e;if(void 0===n)return e;var a,o=e.split(/[#?]/)[0],i="/"===o||o===r?o:(a=o,n?function(e){return e.endsWith("/")?e:e+"/"}(a):function(e){return e.endsWith("/")?e.slice(0,-1):e}(a));return e.replace(o,i)}},18780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.applyTrailingSlash=void 0;var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}})},86010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>k,q_:()=>A,ob:()=>h,PP:()=>L,Ep:()=>m,Hp:()=>g});var r=n(87462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const s=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=l(t),a=l(n);return r!==t||a!==n?e(r,a):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1};var u=n(38776);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function f(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function h(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function g(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&s(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=h(e,t,f(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(59864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),h=s(n),g=0;g{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},36743:(e,t,n)=>{"use strict";n.r(t)},32497:(e,t,n)=>{"use strict";n.r(t)},37253:(e,t,n)=>{"use strict";n.r(t)},74865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
    '};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s{function n(e){let t,n=[];for(let r of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(r))n.push(parseInt(r,10));else if(t=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,r,a,o]=t;if(r&&o){r=parseInt(r),o=parseInt(o);const e=r{var r=n(5826);e.exports=p,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=f;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",c=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],f=n[1],p=n.index;if(l+=e.slice(i,p),i=p+d.length,f)l+=f[1];else{var m=e[i],h=n[2],g=n[3],b=n[4],v=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var E=null!=h&&null!=m&&m!==h,S="+"===y||"*"===y,k="?"===y||"*"===y,x=n[2]||c,C=b||v;r.push({name:g||o++,prefix:h||"",delimiter:x,optional:k,repeat:S,partial:E,asterisk:!!w,pattern:C?u(C):w?".*":"[^"+s(x)+"]+?"})}}return i{"use strict";n.r(t),n.d(t,{default:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);k+=S.value.length,S=S.next){var x=S.value;if(t.length>e.length)return;if(!(x instanceof a)){var C,_=1;if(v){if(!(C=o(E,k,e,b))||C.index>=e.length)break;var T=C.index,P=C.index+C[0].length,A=k;for(A+=S.value.length;T>=A;)A+=(S=S.next).value.length;if(k=A-=S.value.length,S.value instanceof a)continue;for(var D=S;D!==t.tail&&(Ad.reach&&(d.reach=N);var F=S.prev;if(O&&(F=s(t,F,O),k+=O.length),u(t,F,_),S=s(t,F,new a(f,g?r.tokenize(L,g):L,y,L)),R&&s(t,S,R),_>1){var I={cause:f+","+m,reach:N};i(e,t,n,S.prev,k,I),d&&I.reach>d.reach&&(d.reach=I.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s=0&&p(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function u(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function c(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,c={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return c[n]=a,n})).join(""),n,r),f=Object.keys(c);return i=0,function e(t){for(var n=0;n=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=u(c[a]),p=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),p){var h=[p];e(h),m.push.apply(m,h)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var g=r.content;Array.isArray(g)?e(g):e([g])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=o.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++a;var h=f.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(m+p.length),v=[];h&&v.push.apply(v,i([h])),v.push(g),b&&v.push.apply(v,i([b])),"string"==typeof u?l.splice.apply(l,[s,1].concat(v)):u.content=v}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},29901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(29901),a=n(39642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(16500).resolve(t)],delete Prism.languages[e],n(16500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},16500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=16500},39642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(s),m=c;a(m);){for(var h in f={},m){var g=s[h];t(g&&g.modify,(function(e){e in d&&(f[e]=!0)}))}for(var b in d)if(!(b in c))for(var v in p(b))if(v in c){f[b]=!0;break}for(var y in m=f)c[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var a,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)a=r(e);else{var f=i(c.map((function(e){var t=u(e);return delete s[e],t})));o?a=o(f,(function(){return r(e)})):r(e)}return l[e]=a}for(var c in n)u(c);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,c,t,n)}};return w}}();e.exports=t},92703:(e,t,n)=>{"use strict";var r=n(50414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var r=n(67294),a=n(27418),o=n(63840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n