Advanced NeoPixels

The basic setting of Red, Green and Blue colours for NeoPixels can be achieved easily using the Adafruit_NeoPixel library for various microcontroller platforms. There is a lot more that can be achieved with these devices, including animated washes light, breathing glows, alternating candy-cane hues etc.

The NeoPixel article covers the basic wiring and coding concepts. Please check it out first before continuing here. In this article, we will focus on using the FastLED library and exploring some further techniques in creating animated lighting.

In programming addressable LEDs, one of the core concepts to master is in figuring out how to ‘broadcast’ sets of instructions to an entire strip of LEDs, and how to consider a strip of NeoPixels as a very low-resolution display as a coding strategy.

NeoPixels are not ‘displays’!

You might be tempted to try making a giant LED HD screen out from NeoPixels. While you could possibly build this, it is the relative slow rate at which NeoPixels communicate colour data that make this impossible – due to the sequential way data is forwarded down the LED strip, the animations will be exceptionally laggy.

A Reminder on Power Considerations

A typical Neopixel will draw up to 60mA (0.06A). An 8-Neopixel stick will draw up to 480mA (0.48A) at full white brightness. Just like the 12V RGB LED strips, power consumption adds up, so make sure you choose the right 5V power supply. We’ll get by with the USB port’s 500mA in this recipe, but you definitely want to use either a wall-wart transformer, or one of those USB portable power banks for your phones if you want a more robust setup.

FastLED

These following reference pages from the creators of FastLED (Daniel Garcia and Mark Kriegsman) provide all there is to know about utilising this library with NeoPixels:


Wiring & Code

For a refresher on how to use the code in this recipe, click here.

As this article is specific to the use of NeoPixels, the tabs below all work with an Arduino UNO as the basis which should be straightforward to port to other microcontroller platforms. It does require support for FastLED in your platform of choice though.

We will continue to use the potentiometer circuit as per the NeoPixels recipe. Not all examples will utilise the potentiometer.

Breadboard diagram

NeoPixels and potentiometer circuit

NeoPixels and potentiometer circuit

Download NeoPixels (Advanced) Fritzing file

Libraries Used

  • FastLED
    You’ll need to install this from the Library Manager

  • This code shows how a basic FastLED strip is initialised.

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    
    #include <FastLED.h>     // must include the library (assuming you have already installed it)
    
    #define NUM_LEDS 8       // How many LEDs in your strip?
    #define DATA_PIN 12      // Arduino Data pin the first NeoPixel is connected to (via 330ohm)
    
    CRGB leds[NUM_LEDS];     // You must define the array of leds
    
    void setup() { 
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // You must call this in setup()
    }
    
    void loop() {
      // do what you want here to sense things; map values; set colours etc…
      FastLED.show();        // tells FastLED to 'render' the output; you must call this to see changes
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    
  • This code shows how to set colours to individual LEDs.

    First and last LED to Red

    First and last LED to Red

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    #include <FastLED.h>     // must include the library (assuming you have already installed it)
    
    #define NUM_LEDS 8       // How many LEDs in your strip?
    #define DATA_PIN 12      // Arduino Data pin the first NeoPixel is connected to (via 330ohm)
    
    CRGB leds[NUM_LEDS];     // You must define the array of leds
    
    void setup() { 
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // You must call this in setup()
    
      leds[0] = 0xFF0000;             // sets first pixel to RED; you can also use leds[0].setRGB(255,0,0);
      leds[NUM_LEDS - 1] = 0xFF0000;  // LAST pixel to RED (assuming NUM_LEDS was previously #defined)
    }
    
    void loop() {
      // do what you want here to sense things; map values; set colours etc…
      FastLED.show();        // tells FastLED to 'render' the output; you must call this to see changes
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    
  • This code shows how to write alternating colours to a strip.

    Alternating colours

    Alternating colours

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    
    #include <FastLED.h>     // must include the library (assuming you have already installed it)
    
    #define NUM_LEDS 8       // How many LEDs in your strip?
    #define DATA_PIN 12      // Arduino Data pin the first NeoPixel is connected to (via 330ohm)
    
    #define COL_A 0xFF0000   // red
    #define COL_B 0x00FF00   // green
    
    CRGB leds[NUM_LEDS];     // You must define the array of leds
    
    void setup() { 
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // You must call this in setup()
    
      for(int i=0;i<NUM_LEDS;i++) {
        
        if(i%2==0) {          // the modulo operator checks for the remainder of the division. In this case we are checking against odd/even numbers
          leds[i] = COL_A;
        } else {
          leds[i] = COL_B;
        }
      }
    }
    
    void loop() {
      // do what you want here to sense things; map values; set colours etc…
      FastLED.show();        // tells FastLED to 'render' the output; you must call this to see changes
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    
  • This code shows how to write groups of colours to a strip.

    Alternating colours

    Alternating colours

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    
    #include <FastLED.h>     // must include the library (assuming you have already installed it)
    
    #define NUM_LEDS 8       // How many LEDs in your strip?
    #define DATA_PIN 12      // Arduino Data pin the first NeoPixel is connected to (via 330ohm)
    
    #define COL_A 0x00FFFF   // cyan
    #define COL_B 0xFFFF00   // orange
    #define COL_C 0xFF00FF   // magenta
    
    #define GRP1_START 0     // LED index of first colour's starting point
    #define GRP2_START 3     // LED index of second colour's starting point
    #define GRP3_START 5     // LED index of third colour's starting point
    
    CRGB leds[NUM_LEDS];     // You must define the array of leds
    
    void setup() { 
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // You must call this in setup()
    
      for(int i=GRP1_START;i<GRP2_START;i++) {    
          leds[i] = COL_A;
      }
      for(int i=GRP2_START;i<GRP3_START;i++) {
          leds[i] = COL_B;
      }
      for(int i=GRP3_START;i<NUM_LEDS;i++) {    
          leds[i] = COL_C;
      }
    }
    
    void loop() {
      // do what you want here to sense things; map values; set colours etc…
      FastLED.show();        // tells FastLED to 'render' the output; you must call this to see changes
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    
  • This code shows how to set the entire strip to a colour quickly.

    Filling an entire strip yellow

    Filling an entire strip yellow

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
    #include <FastLED.h>     // must include the library (assuming you have already installed it)
    
    #define NUM_LEDS 8       // How many LEDs in your strip?
    #define DATA_PIN 12      // Arduino Data pin the first NeoPixel is connected to (via 330ohm)
    
    CRGB leds[NUM_LEDS];     // You must define the array of leds
    
    void setup() { 
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // You must call this in setup()
    
      fill_solid( &(leds[0]), NUM_LEDS, CRGB( 0, 255, 255) );       // set ALL LEDs to YELLOW
    }
    
    void loop() {
      // do what you want here to sense things; map values; set colours etc…
      FastLED.show();        // tells FastLED to 'render' the output; you must call this to see changes
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    
  • This code shows how to use a Perlin noise generator to achieve a gentle, ‘sparkling’ effect. As the fillnoise function is called inside of loop(), we get an animated effect of the Perlin noise.

    Perlin noise generator

    Perlin noise generator

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    
    #include <FastLED.h>
    
    #define NUM_LEDS 8
    #define DATA_PIN 12
    
    CRGB leds[NUM_LEDS];
    
    // coordinates for noise generator
    static uint16_t x;
    static uint16_t z;    // i.e. time
    
    uint16_t speed = 1;   // a nice starting speed, mixes well with a scale of 100
    uint16_t scale = 300;
    
    // This is the array that we keep our computed noise values in
    uint16_t noise[NUM_LEDS];
    
    void setup() {
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
      FastLED.setBrightness(96);
    
      // Initialize our coordinates to some random values
      x = random16();  // along a single strip
      z = random16();  // the concept of 'time' is applied to an intangible 'z-axis'
    }
    
    // Fill the x/z array of 8-bit noise values using the inoise8 function.
    // Remember, we are using the z-axis as time
    void fillnoise8() {
      for (int i = 0; i < NUM_LEDS; i++) {
        int ioffset = scale * i;
        noise[i] = inoise8(x + ioffset, z);
      }
      z += speed;
    }
    
    void loop() {
      fillnoise8();
      for (int i = 0; i < NUM_LEDS; i++) {
        // leds[i] = CHSV(noise[i], 255, 255); // rainbow noise
    
        // what else can you manipulate for the noise? try commenting the lines below so that only one line is active i.e. uncommented:
        leds[i] = CHSV(180, 255, noise[i]);    // value (brightness) of magenta
        // leds[i] = CHSV(60, noise[i], 160);  // saturation of yellow-green
        leds[i] = CHSV(noise[i], 255, 255);    // random (but soft) rainbow cycle
      }
    
      FastLED.show();
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    
  • This code shows how to animate a point of light that traverses the length of a strip, accelerating and decelerating with the help of a sine wave.

    Sine animated red dot

    Sine animated red dot

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    #include <FastLED.h>
    
    #define NUM_LEDS 8
    #define DATA_PIN 12
    
    CRGB leds[NUM_LEDS];
    
    void setup() {
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
    }
    
    void loop() {
      uint16_t i = beatsin16(50, 0, NUM_LEDS - 1);  // BPM, FIRST, LAST
    
      FastLED.clear();            // 'erase' all LED data
      leds[i] = CRGB(255, 0, 0);  // red dot
    
      FastLED.show();
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    
  • This code builds on the previous, by adding a blur and fading effect to the sine-animated red dot. The potentiometer allows the adjustment of the blur intensity.

    Sine animated and faded red dot

    Sine animated and faded red dot

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    
    #include <FastLED.h>
    
    #define NUM_LEDS 8
    #define DATA_PIN 12
    
    CRGB leds[NUM_LEDS];
    
    void setup() {
      Serial.begin(112500);
    
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
    }
    
    void loop() {
      uint16_t i = beatsin16(50, 0, NUM_LEDS - 1);  // BPM, FIRST, LAST
    
      leds[i] = CRGB(255, 0, 0);  // red dot
    
      EVERY_N_MILLISECONDS(75) {  // special FastLED function that extends timing without the use of delay()
    
        int potValue = analogRead(A0);
        int mappedBlur = map(potValue, 0, 1023, 0, 255);
        fadeLightBy(leds, NUM_LEDS, mappedBlur);  // fade things to black
        blur1d(leds, NUM_LEDS, mappedBlur);       // 'blur' filter
      }
    
      FastLED.show();  // always call this as often as possible
    }
    /*
        Please note that the code provided here is licensed under the MIT license.
    
        The MIT License (MIT)
        Copyright © 2024 Chuan Khoo
    
        Permission is hereby granted, free of charge, to any person obtaining
        a copy of this software and associated documentation files (the
        "Software"), to deal in the Software without restriction, including
        without limitation the rights to use, copy, modify, merge, publish,
        distribute, sublicense, and/or sell copies of the Software, and to
        permit persons to whom the Software is furnished to do so, subject to
        the following conditions:
    
        The above copyright notice and this permission notice shall be included
        in all copies or substantial portions of the Software.
    
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
        THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
        OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
        ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
        OTHER DEALINGS IN THE SOFTWARE.
    */
    

This page was last updated: 23 Sep 2024