text:
---
name: New Service / Section
about: Suggest a service or section to be listed.
title: "Add [Service Name]/[Section Name]"
labels: ''
assignees: ''

---

### Service Name
<!--- Replace what's between "<" and ">" --->
* [Service Name](https://service.site/) - Short service description.
* **License**: <License Type>
* **Why do you think this helps users privacy?**: <Short answer>
* **Under what section should this service be listed?**: <Section (e.g. Cloud Storage)>
* **Additional comments / info**: <Add any additional info here>
<!--- If you want to list more than one service on this same issue, use the same format as above for each service. --->


text:
Most services on this list are Open Source and maintained by volunteers. If you enjoy one of these services please consider making a donation. If you are able to contribute to any project in any way, please consider doing so.

Thank you!

# About this list
This list is intended to gather all the projects that help users to safeguard their privacy and keep their data private in all digital fields and perspectives.

This list may contain some errors and some services may be delisted in the future after discussion. Before going for a service/app make your own investigation, take time to explore and don't trust anybody. This list is just an index of privacy-friendly apps and services but it is not a guarantee that some issues could be discovered in the future for a particular service/app.

If you want to **add** a service, just fork this project and create a PR with you additions. I will review the new services you listed and merge it if they are fine, if there are any kind of doubts we will discuss them on the PR comment section. If you don't want to make a fork+PR, open an issue and propose the service/services.

If you think or find that a listed service is **not respecting** users privacy, please open an issue and we will discuss about it, and if it is needed it will be delisted.

Anybody is welcome to add anything via PR or creating an issue, so if you stumble across this list and you were thinking about creating one you can just contribute to this one here and be a collaborator instead of starting a new one from zero.

repo_name: pluja/awesome-privacy

mime_type: text/plain


text:
Here are some quotes that may reflect why privacy is important and why you should always choose going **the private way**:

> Running a self-hosted live stream server can be done for as cheap as $5/mo, and that’s a much better deal than selling your soul to Facebook, Google or Amazon. ― [Owncast](https://owncast.online/about/)

Companies that diminish and weaken our privacy are not our friends:
> “Friends don’t spy; true friendship is about privacy, too.” ― Stephen King

> Historically, privacy was almost implicit, because it was hard to find and gather information. But in the digital world, whether it's digital cameras or satellites or just what you click on, we need to have more explicit rules - not just for governments but for private companies. ― Bill Gates

> Privacy isn't negotiable.

> The primary reason for window curtains in our house, is to stop people from being able to see in. The reason we don’t want them to see in is because we consider much of what we do inside our homes to be private. Whether that be having dinner at the table, watching a movie with your kids, or even engaging in intimate or sexual acts with your partner. None of these things are illegal by any means but even knowing this, we still keep the curtains and blinds on our windows. We clearly have this strong desire for privacy when it comes to our personal life and the public. - Joshua

> Ultimately, saying that you don't care about privacy because you have nothing to hide is no different from saying you don't care about freedom of speech because you have nothing to say. Or that you don't care about freedom of the press because you don't like to read. Or that you don't care about freedom of religion because you don't believe in God. Or that you don't care about the freedom to peacably assemble because you're a lazy, antisocial agoraphobe. - Edward Snowden

> Without strong encryption, you will be spied on systematically by lots of people. - Whitfield Diffie


text:
# Contributing Guide

## Requirements for a service to be listed:

- [x] Clear privacy-oriented / own your data policy.
- [x] No user-tracking on project website. Only tracking listed under [Analytics](https://github.com/pluja/awesome-privacy#analytics) allowed.
- [x] Open source code is very valuable since it allows you to trust in the project (you can review the code) and not just trust the words. But some service without Open Source code may be added if there is special trust from community and has a good history privacy-wise.

> Every project will need investigation. And of course all listings / additions / PRs and issues are open to discussion as I am human and I may make mistakes.

## Pull Requests

If you are familiar you can add a *section* or a *service* yourself via **pull request**. This is the better way.

If you are not familiar with Github and PRs you can open a new issue and explain what you want to add there.

### Adding a new section
To add a new section copy the following template and complete with the information:

```
## Section Title

<img width="16" src="misc/forbidden.png"> </img> **Avoid**

[OPTIONAL EXPLANATION OF WHY THESE SERVICES ARE BAD]

- Bad Service 1
- Bad Service 2
- Bad Service 3

<img width="16" src="misc/check.png"> </img>  **Instead use**

[OPTIONAL EXPLANATION OF WHY THESE SERVICES ARE GOOD]

- [Good Service 1](https://link-to-source-or-page1) - Little description of the service.
- [Good Service 2](https://link-to-source-or-page2) - Little description of the service.
- [Good Service 2](https://link-to-source-or-page3) - Little description of the service.
```
You also need to add the section to the **Table of Contents (Contents)** at the top of the document:

`- [Section Title](#section-title)`

### Adding a new service

To add a new service just take the following template and add it to the section where it belongs:

`- [Service Name](https://link-to-source-or-page) - Little description of the service`

> You can add either a *good* (use) or a *bad* (avoid) service.


text: Files and miscellaneous


text:
# Contributing

Suggestions and pull requests are highly welcome! Please write the manifests in [recommended format](https://github.com/Ash258/Scoop-Ash258/blob/master/.github/CONTRIBUTING.md#how-to-write-manifests) for easy maintenance.

## Criteria

Manifests may be accepted if it meets the following requirements:

- It doesn't already exists in [Scoop Directory](https://rasa.github.io/scoop-directory/by-apps).
- It exists in Scoop Directory, but its info (version, installer...) is outdated or can be improved.
- It exists in Scoop Directory, but it is a nightly version which can be versioned.

## Submitting to known buckets

If you want to submit a manifest, we suggest you submit it to the [known buckets](https://github.com/lukesampson/scoop/blob/master/buckets.json) as well. However, it may be rejected (possibly because it requires administrator rights) or take too long to be approved, which is why this buckets exist.

Most of the manifests in this bucket won't be submitted to known buckets, however we welcome you do so, but please make sure to attribute this bucket.

## Non-portable apps

Non-portable apps in this bucket won't have the `-np` suffix you may expect in other buckets such as [`nonportable`](https://github.com/TheRandomLabs/scoop-nonportable). This is intended because these apps seldom have portable version, and marking them as non-portable in the name is futile and may lead to confusion.

However, if an app does have portable version/mode which is not available/enabled in this bucket, you are welcome to request a change.

## To open source maintainers

Are you a open source project maintainer? Do you want to provide a easy way to deliver your applications for your Windows users? We are willing to help you! Just [create an issue](https://github.com/kidonng/sushi/issues/new) so we can discuss the details.

repo_name: kidonng/sushi


text:
# 🍣 Sushi

> **Note**: Are you a macOS user? Check out my [Homebrew](https://brew.sh/) tap [**Malt**](https://github.com/kidonng/homebrew-malt).

## Unmaintained

I've switched to macOS in November 2020, and thus lost motivation and environment to maintain this bucket.

Most stuff should still be functional, and I have no plan to turn off automatic updates until the near future. However, there is **no ETA for any new manifests or bug fixes**.

If something doesn't work quite right, I suggest you find an alternative. Meanwhile, I may submit apps in this bucket to the official buckets when I got the time.

Thank you 🤞

---

A tasty and inclusive [Scoop](https://scoop-docs.now.sh/) bucket, providing various kinds of applications.

Spot an error? Find a place which can be improved? Or your favorite application isn't included? Feel free to [submit an issue](https://github.com/kidonng/sushi/issues/new) or make a pull request! **Make sure to read the [contributing guide](CONTRIBUTING.md) first.**

> **Warning**: Some manifests are updated automatically via GitHub Actions to reduce maintenance burden, which _may_ cause installation issues.

## Usage

```powershell
scoop bucket add sushi https://github.com/kidonng/sushi
# The bucket name can be omitted most of the time
scoop install sushi/<app>
```

## Manifests

The lists are sorted alphabetically.

### Featured

-   **evernote**: Note Taking App - Organize Your Notes with Evernote
-   **listary-beta**: A revolutionary search utility
-   **proxychains**: Windows and Cygwin port of proxychains, based on MinHook and DLL Injection
-   **tencent-meeting**: Video conferencing app by Tencent

### All manifests

`#` Require administrator rights (`scoop install sudo`)

`*` May store data outside of Scoop directory

Browsers

-   [firefox-tete009 \* / firefox-tete009-portable](http://www1.plala.or.jp/tete009/en-US/software.html#FIREFOX)

    Portable mode may interfere with other applications, such as MacType's font substitution feature.

Command line

-   [navi](https://github.com/denisidoro/navi)
-   [psfzf](https://github.com/kelleyma49/PSFzf)

Development

-   [cf-tool](https://github.com/xalanq/cf-tool) `*`
-   [cpeditor / cpeditor-beta](https://github.com/cpeditor/cpeditor)
-   [dvm](https://github.com/justjavac/dvm) `*`
-   [salt](https://github.com/Milo123459/salt)
-   [vscode-insiders `*` / vscode-insiders-portable](https://code.visualstudio.com/insiders/)

    Can be updated via Scoop, unlike `extras/vscode-insiders` and `extras/vscode-insiders-portable`.

Fonts

Fonts do **not** need administrator rights to **install**, but they are **needed** to **uninstall**.

-   [cascadia-code-pl](https://github.com/microsoft/cascadia-code)

    Powerline version only, which is different from `nerd-fonts/Cascadia-Code`. Windows Terminal only bundles normal version.

-   [jetbrains-mono](https://github.com/JetBrains/JetBrainsMono)

    Variable format only, which is different from `nerd-fonts/JetBrains-Mono`.

-   [source-han-sans-truetype](https://github.com/be5invis/source-han-sans-ttf)
-   [source-han-serif-truetype](https://github.com/Pal3love/Source-Han-TrueType)

Note-taking

-   [evernote](https://evernote.com/) `*`
-   [obsidian](https://obsidian.md/) `*`
-   [siyuan](https://github.com/siyuan-note/siyuan) `*`

Proxies

-   [clash](https://github.com/Dreamacro/clash)
-   [gun](https://github.com/Qv2ray/gun)
-   [leaf](https://github.com/eycorsican/leaf)
-   [proxychains](https://github.com/shunf4/proxychains-windows)
-   [shadowsocks-go](https://github.com/shadowsocks/go-shadowsocks2)
-   [trojan-go](https://p4gefau1t.github.io/trojan-go/)

Proxies Tools

-   [mellow](https://github.com/mellow-io/mellow) `#` `*`
-   [naivesharp](https://github.com/KevinZonda/NaiveSharp)
-   [outline-server / outline-server-nightly](https://github.com/Jigsaw-Code/outline-server)
-   [shadowsocks-uri-generator](https://github.com/database64128/shadowsocks-uri-generator)
-   [trojan-client-slim](https://github.com/KevinZonda/trojan-client-slim)
-   [trojan-qt5](https://github.com/Trojan-Qt5/Trojan-Qt5)
-   [v2ray-desktop](https://github.com/Dr-Incognito/V2Ray-Desktop) `*`

Qv2ray

> Also checkout [`mochi`](https://github.com/Qv2ray/mochi), Qv2ray's official Scoop bucket which is optimized for Mainland China users.

-   [qv2ray-plugin-command](https://github.com/Qv2ray/QvPlugin-Command)
-   [qv2ray-plugin-naiveproxy](https://github.com/Qv2ray/QvPlugin-NaiveProxy)
-   [qv2ray-plugin-ss](https://github.com/Qv2ray/QvPlugin-SS)
-   [qv2ray-plugin-ssr](https://github.com/Qv2ray/QvPlugin-SSR)
-   [qv2ray-plugin-trojan](https://github.com/Qv2ray/QvPlugin-Trojan)
-   [qv2ray-plugin-trojan-go](https://github.com/Qv2ray/QvPlugin-Trojan-Go)

V2Ray

-   [v2ray-beta](https://github.com/v2fly/v2ray-core)
-   [v2ray-domain-list-community](https://github.com/v2ray/domain-list-community)
-   [v2ray-geoip](https://github.com/v2ray/geoip)
-   [v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat)

Miscellaneous

-   [dotnet-desktop-runtime](https://dotnet.microsoft.com/)

    "Portable version", which is different from `extras/windowsdesktop-runtime`. Copied from [`dorado/dotnet-desktop-runtime`](https://github.com/chawyehsu/dorado/blob/master/bucket/dotnet-desktop-runtime.json).

-   [fontloadersub](https://github.com/yzwduck/FontLoaderSub)
-   [lavfilters](https://github.com/Nevcairiel/LAVFilters) `#`

    Based on [`dorado/lavfilters`](https://github.com/chawyehsu/dorado/blob/master/experiment/lavfilters.json).

-   [listary-beta](https://www.listary.com/beta) `#` `*`

    Had been [renamed](https://github.com/kidonng/sushi/commit/986f8d81625e5a1a5a33ec8bf81cb7b25a543b48) to `listary-beta-np` but was [reverted](https://github.com/kidonng/sushi/commit/b33d21a6c83c44c765fcd6bc8dab9cba820038d4).

-   [pandownload](https://pandownload.com/)

    Copied from [`dorado/pandownload`](https://github.com/chawyehsu/dorado/blob/master/bucket/pandownload.json).

-   [qtpass](https://github.com/IJHack/QtPass)
-   [sandboxie-plus](https://github.com/sandboxie-plus/Sandboxie)
-   [tencent-meeting](https://meeting.tencent.com/) `*`
-   [varpanel](http://implbits.com/products/varpanel/)
-   [wechat](https://pc.weixin.qq.com/) `*`
-   [wnr](https://github.com/RoderickQiu/wnr) `*`
-   [youtube-dl-wpf](https://github.com/database64128/youtube-dl-wpf)

Deprecated

These manifests have been removed from this bucket because there are better/maintained alternatives in other buckets, or no longer installable via Scoop.

-   [android-clt](https://github.com/kidonng/sushi/commit/c90dba491d08ac4b088474513a79381ef33085cd): use `main/android-clt`
-   [clash](https://github.com/kidonng/sushi/commit/36e97cad86f126b2cd62143950eeef08243b5a2e): use `main/clash`
-   [fluent-reader](https://github.com/kidonng/sushi/commit/7d89dfbce165118692bc16e15aecea3cf8e19481): use `extras/fluent-reader`
-   [gping](https://github.com/kidonng/sushi/commit/e3897e1e00479bf15181b1934f91d300c08a2f2f): use `main/gping`
-   microsoft-edge-\*: use [dorado](https://github.com/chawyehsu/dorado)/microsoftedge-\*
-   [naiveproxy](https://github.com/kidonng/sushi/commit/45e3dfb98febf44c3fbd51461d7ba989e4102b7b): use `main/naiveproxy`
-   nali: use `main/nali`
-   [officetoolplus-beta](https://github.com/kidonng/sushi/commit/bf3060c3a5c67678c41f0fa6ca7edeae46a53043): use [dorado](https://github.com/chawyehsu/dorado)/officetoolplus
-   [openhashtab](https://github.com/namazso/OpenHashTab): no longer available via Scoop
-   [proxifier-4](https://www.proxifier.com/): use `extras/proxifier`
-   qv2ray-beta: use `extras/qv2ray`
-   qv2ray-plugin-\*-beta: use `sushi/qv2ray-plugin-*` (without `-beta` suffix)
-   [scoop-completion](https://github.com/kidonng/sushi/commit/e80f84ed601b592d6508323716013457c9dad625): use [dodorz](https://github.com/dodorz/scoop)/scoop-completion
-   [v2ray-unstable](https://github.com/v2fly/V2FlyBleedingEdgeBinary): the repository has been archived
-   v2ray-vless: use `main/xray`
-   [wechatdevtools-32bit](https://github.com/kidonng/sushi/commit/84a1b116472bfb224f4e960696500957b10c44d1): use [dorado](https://github.com/chawyehsu/dorado)/wechatdevtools
-   [xray](https://github.com/XTLS/Xray-core): use `main/xray`


text:
name: Excavator

on:
    workflow_dispatch:

jobs:
    excavate:
        name: Excavate
        runs-on: windows-latest
        steps:
            - uses: actions/checkout@v3
            - name: Excavate
              uses: ScoopInstaller/GithubActions@main
              env:
                  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
                  SKIP_UPDATED: "1"


text:
= Built-in Examples =

image:https://github.com/arduino/arduino-examples/workflows/Compile%20Examples/badge.svg["Compile Examples Status", link="https://github.com/arduino/arduino-examples/actions?workflow=Compile+Examples"]
image:https://github.com/arduino/arduino-examples/workflows/Code%20Formatting%20Check/badge.svg["Code Formatting Check Status", link="https://github.com/arduino/arduino-examples/actions?workflow=Code+Formatting+Check"]
image:https://github.com/arduino/arduino-examples/workflows/Spell%20Check/badge.svg["Spell Check Status", link="https://github.com/arduino/arduino-examples/actions?workflow=Spell+Check"]

These are the example Arduino sketches built in to the Arduino IDE.

They were originally hosted at `https://github.com/arduino/Arduino/tree/master/build/shared`

For more information about these examples please visit their tutorials at +
https://www.arduino.cc/en/Tutorial/BuiltInExamples

repo_name: arduino/arduino-examples

repo_language: Shell


text:
if ! which clang-format &>/dev/null; then
  echo "clang-format not found or not in PATH. Please install: https://github.com/arduino/clang-static-binaries/releases"
  exit 1
fi

find \
  examples \
  \( \
    -name '*.c' -or \
    -name '*.cpp' -or \
    -name '*.h' -or \
    -name '*.ino' -or \
    -name '*.ipp' -or \
    -name '*.tpp' \
  \) \
  -type f \
  -exec \
    clang-format \
      --assume-filename=foo.cpp \
      -i \
      --style=file \
      {} \;


text:
# See: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#about-the-dependabotyml-file
version: 2

updates:
  # Configure check for outdated GitHub Actions actions in workflows.
  # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/dependabot/README.md
  # See: https://docs.github.com/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
  - package-ecosystem: github-actions
    directory: / # Check the repository's workflows under /.github/workflows/
    schedule:
      interval: daily
    labels:
      - "topic: infrastructure"


text:
# Source: https://github.com/arduino/tooling-project-assets/blob/main/issue-templates/forms/general/bug-report.yml
# See: https://docs.github.com/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms

name: Feature request
description: Suggest an enhancement to this project.
labels:
  - "type: enhancement"
body:
  - type: textarea
    id: description
    attributes:
      label: Describe the request
    validations:
      required: true
  - type: textarea
    id: current
    attributes:
      label: Describe the current behavior
      description: |
        What is the current behavior of the project in relation to your request?
        How can we reproduce that behavior?
    validations:
      required: true
  - type: input
    id: project-version
    attributes:
      label: The examples version
      description: |
        Which version of the "built-in examples" are you using?
        _This should be the most recent version available._
    validations:
      required: true
  - type: textarea
    id: additional
    attributes:
      label: Additional context
      description: Add any additional information here.
    validations:
      required: false
  - type: checkboxes
    id: checklist
    attributes:
      label: Issue checklist
      description: Please double-check that you have done each of the following things before submitting the issue.
      options:
        - label: I searched for previous requests in [the issue tracker](https://github.com/arduino/arduino-examples/issues?q=)
          required: true
        - label: I verified the feature was still missing when using the latest version
          required: true
        - label: My request contains all necessary details
          required: true


text:
# Source: https://github.com/arduino/tooling-project-assets/blob/main/issue-templates/template-choosers/general/config.yml
# See: https://docs.github.com/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser

blank_issues_enabled: false
contact_links:
  - name: Learn about using this project
    url: https://github.com/arduino/arduino-examples#readme
    about: Detailed usage documentation is available here.
  - name: Support request
    url: https://forum.arduino.cc/
    about: We can help you out on the Arduino Forum!
  - name: Discuss development work on the project
    url: https://groups.google.com/a/arduino.cc/g/developers
    about: Arduino Developers Mailing List


text:
# Source: https://github.com/arduino/tooling-project-assets/blob/main/issue-templates/forms/general/bug-report.yml
# See: https://docs.github.com/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms

name: Bug report
description: Report a problem with the code or documentation in this repository.
labels:
  - "type: imperfection"
body:
  - type: textarea
    id: description
    attributes:
      label: Describe the problem
    validations:
      required: true
  - type: textarea
    id: reproduce
    attributes:
      label: To reproduce
      description: Provide the specific set of steps we can follow to reproduce the problem.
    validations:
      required: true
  - type: textarea
    id: expected
    attributes:
      label: Expected behavior
      description: What would you expect to happen after following those instructions?
    validations:
      required: true
  - type: input
    id: project-version
    attributes:
      label: The examples version
      description: |
        Which version of the "built-in examples" are you using?
        _This should be the most recent version available._
    validations:
      required: true
  - type: textarea
    id: additional
    attributes:
      label: Additional context
      description: Add any additional information here.
    validations:
      required: false
  - type: checkboxes
    id: checklist
    attributes:
      label: Issue checklist
      description: Please double-check that you have done each of the following things before submitting the issue.
      options:
        - label: I searched for previous reports in [the issue tracker](https://github.com/arduino/arduino-examples/issues?q=)
          required: true
        - label: I verified the problem still occurs when using the latest version
          required: true
        - label: My report contains all necessary details
          required: true


text:
# This workflow compiles the example sketches for one of each distinct type of active official Arduino board.
#
# This requires the use of external components (e.g., libraries, boards platform, toolchain), so it is possible for
# compilations to be broken by bugs in the external components, even though the example itself is perfect.
#
# If this happens, the procedure is:
# - Report the bug to the appropriate issue tracker.
# - Adjust this workflow to remove the compilation for the specific board/sketch combination that is failing due to the
#   bug.
# - Add a comment to the workflow providing the URL of the issue report.
# - Once the bug is fixed and the fix released, revert the commit that removed the failing compilation.
# - If the issue is closed as "wontfix", add a comment to the affected examples documenting the incompatibility and open
#   an issue requesting that the associated tutorials be updated.

name: Compile Examples

on:
  pull_request:
    paths-ignore:
      - "**"
      - "!.github/workflows/compile-examples.ya?ml"
      - "!examples/**"
      - "**.adoc"
      - "**.jpg"
      - "**.md"
      - "**.png"
      - "**.txt"
  push:
    paths-ignore:
      - "**"
      - "!.github/workflows/compile-examples.ya?ml"
      - "!examples/**"
      - "**.adoc"
      - "**.jpg"
      - "**.md"
      - "**.png"
      - "**.txt"
  # Scheduled trigger checks for breakage caused by changes to external resources (libraries, platforms)
  schedule:
    # run every Tuesday at 3 AM UTC
    - cron: "0 3 * * 2"
  # workflow_dispatch event allows the workflow to be triggered manually
  # See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch
  workflow_dispatch:
  # repository_dispatch event allows the workflow to be triggered via the GitHub API
  # See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch
  repository_dispatch:

jobs:
  build:
    name: ${{ matrix.board.fqbn }}
    runs-on: ubuntu-latest

    env:
      # Libraries to install for all boards
      UNIVERSAL_LIBRARIES: |
        - name: Servo
        - name: LiquidCrystal
        - name: CapacitiveSensor

      # Sketch paths to compile (recursive) for all boards
      UNIVERSAL_SKETCH_PATHS: |
        - examples/01.Basics
        - examples/02.Digital/BlinkWithoutDelay
        - examples/02.Digital/Button
        - examples/02.Digital/Debounce
        - examples/02.Digital/DigitalInputPullup
        - examples/02.Digital/StateChangeDetection
        - examples/03.Analog
        - examples/04.Communication/ASCIITable
        - examples/04.Communication/Dimmer
        - examples/04.Communication/Graph
        - examples/04.Communication/Midi
        - examples/04.Communication/PhysicalPixel
        - examples/04.Communication/ReadASCIIString
        - examples/04.Communication/SerialCallResponse
        - examples/04.Communication/SerialCallResponseASCII
        - examples/04.Communication/SerialEvent
        - examples/04.Communication/VirtualColorMixer
        - examples/05.Control
        - examples/06.Sensors
        - examples/07.Display
        - examples/08.Strings/CharacterAnalysis
        - examples/08.Strings/StringAdditionOperator
        - examples/08.Strings/StringAppendOperator
        - examples/08.Strings/StringCaseChanges
        - examples/08.Strings/StringCharacters
        - examples/08.Strings/StringConstructors
        - examples/08.Strings/StringIndexOf
        - examples/08.Strings/StringLength
        - examples/08.Strings/StringLengthTrim
        - examples/08.Strings/StringReplace
        - examples/08.Strings/StringStartsWithEndsWith
        - examples/08.Strings/StringSubstring
        - examples/08.Strings/StringToInt
        - examples/11.ArduinoISP

    strategy:
      fail-fast: false

      matrix:
        board:
          # For testing the Starter Kit examples
          - fqbn: arduino:avr:uno
            usb: false
            serial1: false
            starter-kit: true
            tone: true
            a5: true
          # Adding this in addition to the Uno because it has 1.5 kB less available flash
          - fqbn: arduino:avr:nano
            usb: false
            serial1: false
            starter-kit: false
            tone: true
            a5: true
          - fqbn: arduino:avr:leonardo
            usb: true
            serial1: true
            starter-kit: false
            tone: true
            a5: true
          - fqbn: arduino:megaavr:uno2018:mode=off
            usb: false
            serial1: true
            starter-kit: false
            tone: true
            a5: true
          - fqbn: arduino:samd:mkrzero
            usb: true
            serial1: true
            starter-kit: false
            tone: true
            a5: true
          - fqbn: arduino:mbed_nano:nano33ble
            usb: false
            serial1: true
            starter-kit: false
            tone: true
            a5: true
          - fqbn: arduino:mbed_nano:nanorp2040connect
            usb: false
            serial1: true
            starter-kit: false
            tone: true
            # WiFiNINA library is required to use pins A4-A7.
            a5: false
          - fqbn: arduino:mbed_portenta:envie_m7
            usb: false
            serial1: true
            starter-kit: false
            tone: true
            a5: true
          - fqbn: arduino:sam:arduino_due_x
            usb: true
            serial1: true
            starter-kit: false
            # Bug report: https://github.com/arduino/ArduinoCore-sam/issues/24
            # Change the value to true once it is fixed.
            tone: false
            a5: true

        # Make board type-specific customizations to the matrix jobs
        include:
          - board:
              # Boards with Keyboard+Mouse library compatibility
              usb: true
            # Install these libraries in addition to the ones defined by env.UNIVERSAL_LIBRARIES
            usb-libraries: |
              - name: Keyboard
              - name: Mouse
            # Compile these sketches in addition to the ones defined by env.UNIVERSAL_SKETCH_PATHS
            usb-sketch-paths: |
              - examples/09.USB
          - board:
              usb: false
            usb-libraries: ""
            usb-sketch-paths: ""
          - board:
              # Boards with a Serial1 port
              serial1: true
            serial1-sketch-paths: |
              - examples/04.Communication/MultiSerial
              - examples/04.Communication/SerialPassthrough
          - board:
              serial1: false
            serial1-sketch-paths: ""
          - board:
              starter-kit: true
            starter-kit-sketch-paths: |
              - examples/10.StarterKit_BasicKit
          - board:
              starter-kit: false
            starter-kit-sketch-paths: ""
          - board:
              tone: true
            tone-sketch-paths: |
              - examples/02.Digital/toneKeyboard
              - examples/02.Digital/toneMelody
              - examples/02.Digital/toneMultiple
              - examples/02.Digital/tonePitchFollower
          - board:
              tone: false
            tone-sketch-paths: ""
          - board:
              a5: true
            a5-sketch-paths: |
              - examples/08.Strings/StringComparisonOperators
          - board:
              a5: false
            tone-sketch-paths: ""

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Compile examples
        uses: arduino/compile-sketches@v1
        with:
          fqbn: ${{ matrix.board.fqbn }}
          libraries: |
            ${{ env.UNIVERSAL_LIBRARIES }}
            ${{ matrix.usb-libraries }}
          sketch-paths: |
            ${{ env.UNIVERSAL_SKETCH_PATHS }}
            ${{ matrix.usb-sketch-paths }}
            ${{ matrix.serial1-sketch-paths }}
            ${{ matrix.starter-kit-sketch-paths }}
            ${{ matrix.tone-sketch-paths }}


text:
name: Code Formatting Check

on:
  pull_request:
    paths:
      - ".github/workflows/code-formatting-check.yml"
      - ".clang-format"
      - "examples_formatter.sh"
      - "examples/**"
  push:
    paths:
      - ".github/workflows/code-formatting-check.yml"
      - ".clang-format"
      - "examples_formatter.sh"
      - "examples/**"

jobs:
  check-formatting:
    runs-on: ubuntu-latest

    env:
      # See: https://github.com/arduino/arduino-ide/blob/main/arduino-ide-extension/package.json
      CLANG_FORMAT_VERSION: 14.0.0

    steps:
      - name: Set environment variables
        run: |
          # See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable
          echo "CLANG_FORMAT_INSTALL_PATH=${{ runner.temp }}/clang-format" >> "$GITHUB_ENV"

      - name: Checkout
        uses: actions/checkout@v3

      - name: Download ClangFormat
        id: download
        uses: MrOctopus/download-asset-action@1.0
        with:
          repository: arduino/clang-static-binaries
          tag: ${{ env.CLANG_FORMAT_VERSION }}
          asset: clang-format_${{ env.CLANG_FORMAT_VERSION }}_Linux_64bit.tar.bz2
          target: ${{ env.CLANG_FORMAT_INSTALL_PATH }}

      - name: Install ClangFormat
        run: |
          cd "${{ env.CLANG_FORMAT_INSTALL_PATH }}"
          tar --extract --file="${{ steps.download.outputs.name }}"
          # Add installation to PATH:
          # See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path
          echo "${{ env.CLANG_FORMAT_INSTALL_PATH }}/clang_Linux_64bit" >> "$GITHUB_PATH"

      - name: Format examples
        run: ./examples_formatter.sh

      - name: Check formatting
        run: |
          if ! git diff --color --exit-code; then
            echo "Please do an Auto Format on the sketches:"
            echo "Arduino IDE: Tools > Auto Format"
            echo "Arduino Web Editor: Ctrl + B"
            exit 1
          fi


text:
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/sync-labels.md
name: Sync Labels

# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows
on:
  push:
    paths:
      - ".github/workflows/sync-labels.ya?ml"
      - ".github/label-configuration-files/*.ya?ml"
  pull_request:
    paths:
      - ".github/workflows/sync-labels.ya?ml"
      - ".github/label-configuration-files/*.ya?ml"
  schedule:
    # Run daily at 8 AM UTC to sync with changes to shared label configurations.
    - cron: "0 8 * * *"
  workflow_dispatch:
  repository_dispatch:

env:
  CONFIGURATIONS_FOLDER: .github/label-configuration-files
  CONFIGURATIONS_ARTIFACT: label-configuration-files

jobs:
  check:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Download JSON schema for labels configuration file
        id: download-schema
        uses: carlosperate/download-file-action@v2
        with:
          file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/arduino-tooling-gh-label-configuration-schema.json
          location: ${{ runner.temp }}/label-configuration-schema

      - name: Install JSON schema validator
        run: |
          sudo npm install \
            --global \
            ajv-cli \
            ajv-formats

      - name: Validate local labels configuration
        run: |
          # See: https://github.com/ajv-validator/ajv-cli#readme
          ajv validate \
            --all-errors \
            -c ajv-formats \
            -s "${{ steps.download-schema.outputs.file-path }}" \
            -d "${{ env.CONFIGURATIONS_FOLDER }}/*.{yml,yaml}"

  download:
    needs: check
    runs-on: ubuntu-latest

    strategy:
      matrix:
        filename:
          # Filenames of the shared configurations to apply to the repository in addition to the local configuration.
          # https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/sync-labels
          - universal.yml

    steps:
      - name: Download
        uses: carlosperate/download-file-action@v2
        with:
          file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/${{ matrix.filename }}

      - name: Pass configuration files to next job via workflow artifact
        uses: actions/upload-artifact@v3
        with:
          path: |
            *.yaml
            *.yml
          if-no-files-found: error
          name: ${{ env.CONFIGURATIONS_ARTIFACT }}

  sync:
    needs: download
    runs-on: ubuntu-latest

    steps:
      - name: Set environment variables
        run: |
          # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
          echo "MERGED_CONFIGURATION_PATH=${{ runner.temp }}/labels.yml" >> "$GITHUB_ENV"

      - name: Determine whether to dry run
        id: dry-run
        if: >
          github.event_name == 'pull_request' ||
          (
            (
              github.event_name == 'push' ||
              github.event_name == 'workflow_dispatch'
            ) &&
            github.ref != format('refs/heads/{0}', github.event.repository.default_branch)
          )
        run: |
          # Use of this flag in the github-label-sync command will cause it to only check the validity of the
          # configuration.
          echo "::set-output name=flag::--dry-run"

      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Download configuration files artifact
        uses: actions/download-artifact@v3
        with:
          name: ${{ env.CONFIGURATIONS_ARTIFACT }}
          path: ${{ env.CONFIGURATIONS_FOLDER }}

      - name: Remove unneeded artifact
        uses: geekyeggo/delete-artifact@v2
        with:
          name: ${{ env.CONFIGURATIONS_ARTIFACT }}

      - name: Merge label configuration files
        run: |
          # Merge all configuration files
          shopt -s extglob
          cat "${{ env.CONFIGURATIONS_FOLDER }}"/*.@(yml|yaml) > "${{ env.MERGED_CONFIGURATION_PATH }}"

      - name: Install github-label-sync
        run: sudo npm install --global github-label-sync

      - name: Sync labels
        env:
          GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # See: https://github.com/Financial-Times/github-label-sync
          github-label-sync \
            --labels "${{ env.MERGED_CONFIGURATION_PATH }}" \
            ${{ steps.dry-run.outputs.flag }} \
            ${{ github.repository }}


text:
name: Spell Check

on:
  pull_request:
  push:
  schedule:
    # run every Tuesday at 3 AM UTC
    - cron: "0 3 * * 2"

jobs:
  spellcheck:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      # See: https://github.com/codespell-project/actions-codespell/blob/master/README.md
      - name: Spell check
        uses: codespell-project/actions-codespell@master
        with:
          check_filenames: true
          check_hidden: true
          # In the event of a false positive, add the word in all lower case to this file:
          ignore_words_file: extras/codespell-ignore-words-list.txt


text:
/*
  Row-Column Scanning an 8x8 LED matrix with X-Y input

  This example controls an 8x8 LED matrix using two analog inputs.

  This example works for the Lumex LDM-24488NI Matrix. See
  https://sigma.octopart.com/140413/datasheet/Lumex-LDM-24488NI.pdf
  for the pin connections.

  For other LED cathode column matrixes, you should only need to change the pin
  numbers in the row[] and column[] arrays.

  rows are the anodes
  cols are the cathodes
  ---------

  Pin numbers:
  Matrix:
  - digital pins 2 through 13,
  - analog pins 2 through 5 used as digital 16 through 19
  Potentiometers:
  - center pins are attached to analog pins 0 and 1, respectively
  - side pins attached to +5V and ground, respectively

  created 27 May 2009
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/RowColumnScanning
*/

// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

// cursor position:
int x = 5;
int y = 5;

void setup() {
  // initialize the I/O pins as outputs iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }

  // initialize the pixel matrix:
  for (int x = 0; x < 8; x++) {
    for (int y = 0; y < 8; y++) {
      pixels[x][y] = HIGH;
    }
  }
}

void loop() {
  // read input:
  readSensors();

  // draw the screen:
  refreshScreen();
}

void readSensors() {
  // turn off the last position:
  pixels[x][y] = HIGH;
  // read the sensors for X and Y values:
  x = 7 - map(analogRead(A0), 0, 1023, 0, 7);
  y = map(analogRead(A1), 0, 1023, 0, 7);
  // set the new pixel position low so that the LED will turn on in the next
  // screen refresh:
  pixels[x][y] = LOW;
}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}


text:
/*
  LED bar graph

  Turns on a series of LEDs based on the value of an analog sensor.
  This is a simple way to make a bar graph display. Though this graph uses 10
  LEDs, you can use any number by changing the LED count and the pins in the
  array.

  This method can be used to control any series of digital outputs that depends
  on an analog input.

  The circuit:
  - LEDs from pins 2 through 11 to ground

  created 4 Sep 2010
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/BarGraph
*/

// these constants won't change:
const int analogPin = A0;  // the pin that the potentiometer is attached to
const int ledCount = 10;   // the number of LEDs in the bar graph

int ledPins[] = {
  2, 3, 4, 5, 6, 7, 8, 9, 10, 11
};  // an array of pin numbers to which LEDs are attached

void setup() {
  // loop over the pin array and set them all to output:
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
    pinMode(ledPins[thisLed], OUTPUT);
  }
}

void loop() {
  // read the potentiometer:
  int sensorReading = analogRead(analogPin);
  // map the result to a range from 0 to the number of LEDs:
  int ledLevel = map(sensorReading, 0, 1023, 0, ledCount);

  // loop over the LED array:
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
    // if the array element's index is less than ledLevel,
    // turn the pin for this element on:
    if (thisLed < ledLevel) {
      digitalWrite(ledPins[thisLed], HIGH);
    }
    // turn off all pins higher than the ledLevel:
    else {
      digitalWrite(ledPins[thisLed], LOW);
    }
  }
}


text:
/*
  Character analysis operators

  Examples using the character analysis operators.
  Send any byte and the sketch will tell you about it.

  created 29 Nov 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/CharacterAnalysis
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("send any byte and I'll tell you everything I can about it");
  Serial.println();
}

void loop() {
  // get any incoming bytes:
  if (Serial.available() > 0) {
    int thisChar = Serial.read();

    // say what was sent:
    Serial.print("You sent me: \'");
    Serial.write(thisChar);
    Serial.print("\'  ASCII Value: ");
    Serial.println(thisChar);

    // analyze what was sent:
    if (isAlphaNumeric(thisChar)) {
      Serial.println("it's alphanumeric");
    }
    if (isAlpha(thisChar)) {
      Serial.println("it's alphabetic");
    }
    if (isAscii(thisChar)) {
      Serial.println("it's ASCII");
    }
    if (isWhitespace(thisChar)) {
      Serial.println("it's whitespace");
    }
    if (isControl(thisChar)) {
      Serial.println("it's a control character");
    }
    if (isDigit(thisChar)) {
      Serial.println("it's a numeric digit");
    }
    if (isGraph(thisChar)) {
      Serial.println("it's a printable character that's not whitespace");
    }
    if (isLowerCase(thisChar)) {
      Serial.println("it's lower case");
    }
    if (isPrintable(thisChar)) {
      Serial.println("it's printable");
    }
    if (isPunct(thisChar)) {
      Serial.println("it's punctuation");
    }
    if (isSpace(thisChar)) {
      Serial.println("it's a space character");
    }
    if (isUpperCase(thisChar)) {
      Serial.println("it's upper case");
    }
    if (isHexadecimalDigit(thisChar)) {
      Serial.println("it's a valid hexadecimaldigit (i.e. 0 - 9, a - F, or A - F)");
    }

    // add some space and ask for another byte:
    Serial.println();
    Serial.println("Give me another byte:");
    Serial.println();
  }
}


text:
/*
  String length()

  Examples of how to use length() in a String.
  Open the Serial Monitor and start sending characters to see the results.

  created 1 Aug 2010
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringLengthTrim
*/

String txtMsg = "";                               // a string for incoming text
unsigned int lastStringLength = txtMsg.length();  // previous length of the String

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString  length():");
  Serial.println();
}

void loop() {
  // add any incoming characters to the String:
  while (Serial.available() > 0) {
    char inChar = Serial.read();
    txtMsg += inChar;
  }

  // print the message and a notice if it's changed:
  if (txtMsg.length() != lastStringLength) {
    Serial.println(txtMsg);
    Serial.println(txtMsg.length());
    // if the String's longer than 140 characters, complain:
    if (txtMsg.length() < 140) {
      Serial.println("That's a perfectly acceptable text message");
    } else {
      Serial.println("That's too long for a text message.");
    }
    // note the length for next time through the loop:
    lastStringLength = txtMsg.length();
  }
}


text:
/*
  String charAt() and setCharAt()

  Examples of how to get and set characters of a String

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringCharacters
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("\n\nString charAt() and setCharAt():");
}

void loop() {
  // make a String to report a sensor reading:
  String reportString = "SensorReading: 456";
  Serial.println(reportString);

  // the reading's most significant digit is at position 15 in the reportString:
  char mostSignificantDigit = reportString.charAt(15);

  String message = "Most significant digit of the sensor reading is: ";
  Serial.println(message + mostSignificantDigit);

  // add blank space:
  Serial.println();

  // you can also set the character of a String. Change the : to a = character
  reportString.setCharAt(13, '=');
  Serial.println(reportString);

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  Appending to Strings using the += operator and concat()

  Examples of how to append different data types to Strings

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringAppendOperator
*/

String stringOne, stringTwo;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  stringOne = String("Sensor ");
  stringTwo = String("value");
  // send an intro:
  Serial.println("\n\nAppending to a String:");
  Serial.println();
}

void loop() {
  Serial.println(stringOne);  // prints  "Sensor "

  // adding a string to a String:
  stringOne += stringTwo;
  Serial.println(stringOne);  // prints "Sensor value"

  // adding a constant string to a String:
  stringOne += " for input ";
  Serial.println(stringOne);  // prints "Sensor value for input"

  // adding a constant character to a String:
  stringOne += 'A';
  Serial.println(stringOne);  // prints "Sensor value for input A"

  // adding a constant integer to a String:
  stringOne += 0;
  Serial.println(stringOne);  // prints "Sensor value for input A0"

  // adding a constant string to a String:
  stringOne += ": ";
  Serial.println(stringOne);  // prints "Sensor value for input"

  // adding a variable integer to a String:
  stringOne += analogRead(A0);
  Serial.println(stringOne);  // prints "Sensor value for input A0: 456" or whatever analogRead(A0) is

  Serial.println("\n\nchanging the Strings' values");
  stringOne = "A long integer: ";
  stringTwo = "The millis(): ";

  // adding a constant long integer to a String:
  stringOne += 123456789;
  Serial.println(stringOne);  // prints "A long integer: 123456789"

  // using concat() to add a long variable to a String:
  stringTwo.concat(millis());
  Serial.println(stringTwo);  // prints "The millis(): 43534" or whatever the value of the millis() is

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  String to Integer conversion

  Reads a serial input string until it sees a newline, then converts the string
  to a number if the characters are digits.

  The circuit:
  - No external components needed.

  created 29 Nov 2010
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringToInt
*/

String inString = "";  // string to hold input

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString toInt():");
  Serial.println();
}

void loop() {
  // Read serial input:
  while (Serial.available() > 0) {
    int inChar = Serial.read();
    if (isDigit(inChar)) {
      // convert the incoming byte to a char and add it to the string:
      inString += (char)inChar;
    }
    // if you get a newline, print the string, then the string's value:
    if (inChar == '\n') {
      Serial.print("Value:");
      Serial.println(inString.toInt());
      Serial.print("String: ");
      Serial.println(inString);
      // clear the string for new input:
      inString = "";
    }
  }
}


text:
/*
  String substring()

  Examples of how to use substring in a String

  created 27 Jul 2010,
  modified 2 Apr 2012
  by Zach Eveland

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringSubstring
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString  substring():");
  Serial.println();
}

void loop() {
  // Set up a String:
  String stringOne = "Content-Type: text/html";
  Serial.println(stringOne);

  // substring(index) looks for the substring from the index position to the end:
  if (stringOne.substring(19) == "html") {
    Serial.println("It's an html file");
  }
  // you can also look for a substring in the middle of a string:
  if (stringOne.substring(14, 18) == "text") {
    Serial.println("It's a text-based file");
  }

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  Comparing Strings

  Examples of how to compare Strings using the comparison operators

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringComparisonOperators
*/

String stringOne, stringTwo;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  stringOne = String("this");
  stringTwo = String("that");
  // send an intro:
  Serial.println("\n\nComparing Strings:");
  Serial.println();
}

void loop() {
  // two Strings equal:
  if (stringOne == "this") {
    Serial.println("StringOne == \"this\"");
  }
  // two Strings not equal:
  if (stringOne != stringTwo) {
    Serial.println(stringOne + " =! " + stringTwo);
  }

  // two Strings not equal (case sensitivity matters):
  stringOne = "This";
  stringTwo = "this";
  if (stringOne != stringTwo) {
    Serial.println(stringOne + " =! " + stringTwo);
  }
  // you can also use equals() to see if two Strings are the same:
  if (stringOne.equals(stringTwo)) {
    Serial.println(stringOne + " equals " + stringTwo);
  } else {
    Serial.println(stringOne + " does not equal " + stringTwo);
  }

  // or perhaps you want to ignore case:
  if (stringOne.equalsIgnoreCase(stringTwo)) {
    Serial.println(stringOne + " equals (ignoring case) " + stringTwo);
  } else {
    Serial.println(stringOne + " does not equal (ignoring case) " + stringTwo);
  }

  // a numeric String compared to the number it represents:
  stringOne = "1";
  int numberOne = 1;
  if (stringOne.toInt() == numberOne) {
    Serial.println(stringOne + " = " + numberOne);
  }

  // two numeric Strings compared:
  stringOne = "2";
  stringTwo = "1";
  if (stringOne >= stringTwo) {
    Serial.println(stringOne + " >= " + stringTwo);
  }

  // comparison operators can be used to compare Strings for alphabetic sorting too:
  stringOne = String("Brown");
  if (stringOne < "Charles") {
    Serial.println(stringOne + " < Charles");
  }

  if (stringOne > "Adams") {
    Serial.println(stringOne + " > Adams");
  }

  if (stringOne <= "Browne") {
    Serial.println(stringOne + " <= Browne");
  }

  if (stringOne >= "Brow") {
    Serial.println(stringOne + " >= Brow");
  }

  // the compareTo() operator also allows you to compare Strings
  // it evaluates on the first character that's different.
  // if the first character of the String you're comparing to comes first in
  // alphanumeric order, then compareTo() is greater than 0:
  stringOne = "Cucumber";
  stringTwo = "Cucuracha";
  if (stringOne.compareTo(stringTwo) < 0) {
    Serial.println(stringOne + " comes before " + stringTwo);
  } else {
    Serial.println(stringOne + " comes after " + stringTwo);
  }

  delay(10000);  // because the next part is a loop:

  // compareTo() is handy when you've got Strings with numbers in them too:

  while (true) {
    stringOne = "Sensor: ";
    stringTwo = "Sensor: ";

    stringOne += analogRead(A0);
    stringTwo += analogRead(A5);

    if (stringOne.compareTo(stringTwo) < 0) {
      Serial.println(stringOne + " comes before " + stringTwo);
    } else {
      Serial.println(stringOne + " comes after " + stringTwo);
    }
  }
}


text:
/*
  String replace()

  Examples of how to replace characters or substrings of a String

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringReplace
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString replace:\n");
  Serial.println();
}

void loop() {
  String stringOne = "<html><head><body>";
  Serial.println(stringOne);
  // replace() changes all instances of one substring with another:
  // first, make a copy of the original string:
  String stringTwo = stringOne;
  // then perform the replacements:
  stringTwo.replace("<", "</");
  // print the original:
  Serial.println("Original string: " + stringOne);
  // and print the modified string:
  Serial.println("Modified string: " + stringTwo);

  // you can also use replace() on single characters:
  String normalString = "bookkeeper";
  Serial.println("normal: " + normalString);
  String leetString = normalString;
  leetString.replace('o', '0');
  leetString.replace('e', '3');
  Serial.println("l33tspeak: " + leetString);

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  String startWith() and endsWith()

  Examples of how to use startsWith() and endsWith() in a String

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringStartsWithEndsWith
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString startsWith() and endsWith():");
  Serial.println();
}

void loop() {
  // startsWith() checks to see if a String starts with a particular substring:
  String stringOne = "HTTP/1.1 200 OK";
  Serial.println(stringOne);
  if (stringOne.startsWith("HTTP/1.1")) {
    Serial.println("Server's using http version 1.1");
  }

  // you can also look for startsWith() at an offset position in the string:
  stringOne = "HTTP/1.1 200 OK";
  if (stringOne.startsWith("200 OK", 9)) {
    Serial.println("Got an OK from the server");
  }

  // endsWith() checks to see if a String ends with a particular character:
  String sensorReading = "sensor = ";
  sensorReading += analogRead(A0);
  Serial.print(sensorReading);
  if (sensorReading.endsWith("0")) {
    Serial.println(". This reading is divisible by ten");
  } else {
    Serial.println(". This reading is not divisible by ten");
  }

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  String Case changes

  Examples of how to change the case of a String

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringCaseChanges
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString case changes:");
  Serial.println();
}

void loop() {
  // toUpperCase() changes all letters to upper case:
  String stringOne = "";
  Serial.println(stringOne);
  stringOne.toUpperCase();
  Serial.println(stringOne);

  // toLowerCase() changes all letters to lower case:
  String stringTwo = "";
  Serial.println(stringTwo);
  stringTwo.toLowerCase();
  Serial.println(stringTwo);

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  String length() and trim()

  Examples of how to use length() and trim() in a String

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringLengthTrim
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString length() and trim():");
  Serial.println();
}

void loop() {
  // here's a String with empty spaces at the end (called white space):
  String stringOne = "Hello!       ";
  Serial.print(stringOne);
  Serial.print("<--- end of string. Length: ");
  Serial.println(stringOne.length());

  // trim the white space off the string:
  stringOne.trim();
  Serial.print(stringOne);
  Serial.print("<--- end of trimmed string. Length: ");
  Serial.println(stringOne.length());

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  String constructors

  Examples of how to create Strings from other data types

  created 27 Jul 2010
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringConstructors
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString Constructors:");
  Serial.println();
}

void loop() {
  // using a constant String:
  String stringOne = "Hello String";
  Serial.println(stringOne);  // prints "Hello String"

  // converting a constant char into a String:
  stringOne = String('a');
  Serial.println(stringOne);  // prints "a"

  // converting a constant string into a String object:
  String stringTwo = String("This is a string");
  Serial.println(stringTwo);  // prints "This is a string"

  // concatenating two strings:
  stringOne = String(stringTwo + " with more");
  // prints "This is a string with more":
  Serial.println(stringOne);

  // using a constant integer:
  stringOne = String(13);
  Serial.println(stringOne);  // prints "13"

  // using an int and a base:
  stringOne = String(analogRead(A0), DEC);
  // prints "453" or whatever the value of analogRead(A0) is
  Serial.println(stringOne);

  // using an int and a base (hexadecimal):
  stringOne = String(45, HEX);
  // prints "2d", which is the hexadecimal version of decimal 45:
  Serial.println(stringOne);

  // using an int and a base (binary)
  stringOne = String(255, BIN);
  // prints "11111111" which is the binary value of 255
  Serial.println(stringOne);

  // using a long and a base:
  stringOne = String(millis(), DEC);
  // prints "123456" or whatever the value of millis() is:
  Serial.println(stringOne);

  // using a float and the right decimal places:
  stringOne = String(5.698, 3);
  Serial.println(stringOne);

  // using a float and less decimal places to use rounding:
  stringOne = String(5.698, 2);
  Serial.println(stringOne);

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  Adding Strings together

  Examples of how to add Strings together
  You can also add several different data types to String, as shown here:

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringAdditionOperator
*/

// declare three Strings:
String stringOne, stringTwo, stringThree;

void setup() {
  // initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  stringOne = String("You added ");
  stringTwo = String("this string");
  stringThree = String();
  // send an intro:
  Serial.println("\n\nAdding Strings together (concatenation):");
  Serial.println();
}

void loop() {
  // adding a constant integer to a String:
  stringThree = stringOne + 123;
  Serial.println(stringThree);  // prints "You added 123"

  // adding a constant long integer to a String:
  stringThree = stringOne + 123456789;
  Serial.println(stringThree);  // prints "You added 123456789"

  // adding a constant character to a String:
  stringThree = stringOne + 'A';
  Serial.println(stringThree);  // prints "You added A"

  // adding a constant string to a String:
  stringThree = stringOne + "abc";
  Serial.println(stringThree);  // prints "You added abc"

  stringThree = stringOne + stringTwo;
  Serial.println(stringThree);  // prints "You added this string"

  // adding a variable integer to a String:
  int sensorValue = analogRead(A0);
  stringOne = "Sensor value: ";
  stringThree = stringOne + sensorValue;
  Serial.println(stringThree);  // prints "Sensor Value: 401" or whatever value analogRead(A0) has

  // adding a variable long integer to a String:
  stringOne = "millis() value: ";
  stringThree = stringOne + millis();
  Serial.println(stringThree);  // prints "The millis: 345345" or whatever value millis() has

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  String indexOf() and lastIndexOf() functions

  Examples of how to evaluate, look for, and replace characters in a String

  created 27 Jul 2010
  modified 2 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/StringIndexOf
*/

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // send an intro:
  Serial.println("\n\nString indexOf() and lastIndexOf()  functions:");
  Serial.println();
}

void loop() {
  // indexOf() returns the position (i.e. index) of a particular character in a
  // String. For example, if you were parsing HTML tags, you could use it:
  String stringOne = "";
  int firstClosingBracket = stringOne.indexOf('>');
  Serial.println("The index of > in the string " + stringOne + " is " + firstClosingBracket);

  stringOne = "";
  int secondOpeningBracket = firstClosingBracket + 1;
  int secondClosingBracket = stringOne.indexOf('>', secondOpeningBracket);
  Serial.println("The index of  the second > in the string " + stringOne + " is " + secondClosingBracket);

  // you can also use indexOf() to search for Strings:
  stringOne = "";
  int bodyTag = stringOne.indexOf("");
  Serial.println("The index of the body tag in the string " + stringOne + " is " + bodyTag);

  stringOne = "

item
item
item
";
  int firstListItem = stringOne.indexOf("
");
  int secondListItem = stringOne.indexOf("
", firstListItem + 1);
  Serial.println("The index of the second list tag in the string " + stringOne + " is " + secondListItem);

  // lastIndexOf() gives you the last occurrence of a character or string:
  int lastOpeningBracket = stringOne.lastIndexOf('<');
  Serial.println("The index of the last < in the string " + stringOne + " is " + lastOpeningBracket);

  int lastListItem = stringOne.lastIndexOf("
");
  Serial.println("The index of the last list tag in the string " + stringOne + " is " + lastListItem);

  // lastIndexOf() can also search for a string:
  stringOne = "
Lorem ipsum dolor sit amet

Ipsem

Quod
";
  int lastParagraph = stringOne.lastIndexOf("<p");
  int secondLastGraf = stringOne.lastIndexOf("<p", lastParagraph - 1);
  Serial.println("The index of the second to last paragraph tag " + stringOne + " is " + secondLastGraf);

  // do nothing while true:
  while (true)
    ;
}


text:
/*
  DigitalReadSerial

  Reads a digital input on pin 2, prints the result to the Serial Monitor

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/DigitalReadSerial
*/

// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input pin:
  int buttonState = digitalRead(pushButton);
  // print out the state of the button:
  Serial.println(buttonState);
  delay(1);  // delay in between reads for stability
}


text:
void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}


text:
/*
  Fade

  This example shows how to fade an LED on pin 9 using the analogWrite()
  function.

  The analogWrite() function uses PWM, so if you want to change the pin you're
  using, be sure to use another PWM capable pin. On most Arduino, the PWM pins
  are identified with a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Fade
*/

int led = 9;         // the PWM pin the LED is attached to
int brightness = 0;  // how bright the LED is
int fadeAmount = 5;  // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}


text:
/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                      // wait for a second
}


text:
/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/AnalogReadSerial
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);  // delay in between reads for stability
}


text:
/*
  ReadAnalogVoltage

  Reads an analog input on pin 0, converts it to voltage, and prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/ReadAnalogVoltage
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
}


text:
/*
  SerialPassthrough sketch

  Some boards, like the Arduino 101, the MKR1000, Zero, or the Micro, have one
  hardware serial port attached to Digital pins 0-1, and a separate USB serial
  port attached to the IDE Serial Monitor. This means that the "serial
  passthrough" which is possible with the Arduino UNO (commonly used to interact
  with devices/shields that require configuration via serial AT commands) will
  not work by default.

  This sketch allows you to emulate the serial passthrough behaviour. Any text
  you type in the IDE Serial monitor will be written out to the serial port on
  Digital pins 0 and 1, and vice-versa.

  On the 101, MKR1000, Zero, and Micro, "Serial" refers to the USB Serial port
  attached to the Serial Monitor, and "Serial1" refers to the hardware serial
  port attached to pins 0 and 1. This sketch will emulate Serial passthrough
  using those two Serial ports on the boards mentioned above, but you can change
  these names to connect any two serial ports on a board that has multiple ports.

  created 23 May 2016
  by Erik Nyquist

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/SerialPassthrough
*/

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  if (Serial.available()) {        // If anything comes in Serial (USB),
    Serial1.write(Serial.read());  // read it and send it out Serial1 (pins 0 & 1)
  }

  if (Serial1.available()) {       // If anything comes in Serial1 (pins 0 & 1)
    Serial.write(Serial1.read());  // read it and send it out Serial (USB)
  }
}


text:
/*
  Serial Event example

  When new serial data arrives, this sketch adds it to a String.
  When a newline is received, the loop prints the string and clears it.

  A good test for this is to try it with a GPS receiver that sends out
  NMEA 0183 sentences.

  NOTE: The serialEvent() feature is not available on the Leonardo, Micro, or
  other ATmega32U4 based boards.

  created 9 May 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/SerialEvent
*/

String inputString = "";      // a String to hold incoming data
bool stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.println(inputString);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag so the main loop can
    // do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}


text:
/*
  This example reads three analog sensors (potentiometers are easiest) and sends
  their values serially. The Processing and Max/MSP programs at the bottom take
  those three values and use them to change the background color of the screen.

  The circuit:
  - potentiometers attached to analog inputs 0, 1, and 2

  created 2 Dec 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe and Scott Fitzgerald

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/VirtualColorMixer
*/

const int redPin = A0;    // sensor to control red color
const int greenPin = A1;  // sensor to control green color
const int bluePin = A2;   // sensor to control blue color

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print(analogRead(redPin));
  Serial.print(",");
  Serial.print(analogRead(greenPin));
  Serial.print(",");
  Serial.println(analogRead(bluePin));
}

/* Processing code for this example

  // This example code is in the public domain.

  import processing.serial.*;

  float redValue = 0;        // red value
  float greenValue = 0;      // green value
  float blueValue = 0;       // blue value

  Serial myPort;

  void setup() {
    size(200, 200);

    // List all the available serial ports
    // if using Processing 2.1 or later, use Serial.printArray()
    println(Serial.list());

    // I know that the first port in the serial list on my Mac is always my
    // Arduino, so I open Serial.list()[0].
    // Open whatever port is the one you're using.
    myPort = new Serial(this, Serial.list()[0], 9600);
    // don't generate a serialEvent() unless you get a newline character:
    myPort.bufferUntil('\n');
  }

  void draw() {
    // set the background color with the color values:
    background(redValue, greenValue, blueValue);
  }

  void serialEvent(Serial myPort) {
    // get the ASCII string:
    String inString = myPort.readStringUntil('\n');

    if (inString != null) {
      // trim off any whitespace:
      inString = trim(inString);
      // split the string on the commas and convert the resulting substrings
      // into an integer array:
      float[] colors = float(split(inString, ","));
      // if the array has at least three elements, you know you got the whole
      // thing.  Put the numbers in the color variables:
      if (colors.length >= 3) {
        // map them to the range 0-255:
        redValue = map(colors[0], 0, 1023, 0, 255);
        greenValue = map(colors[1], 0, 1023, 0, 255);
        blueValue = map(colors[2], 0, 1023, 0, 255);
      }
    }
  }

*/

/* Max/MSP patch for this example

  ----------begin_max5_patcher----------
  1512.3oc4Z00aaaCE8YmeED9ktB35xOjrj1aAsXX4g8xZQeYoXfVh1gqRjdT
  TsIsn+2K+PJUovVVJ1VMdCAvxThV7bO7b48dIyWtXxzkxaYkSA+J3u.Sl7kK
  lLwcK6MlT2dxzB5so4zRW2lJXeRt7elNy+HM6Vs61uDDzbOYkNmo02sg4euS
  4BSede8S2P0o2vEq+aEKU66PPP7b3LPHDauPvyCmAvv4v6+M7L2XXF2WfCaF
  lURgVPKbCxzKUbZdySDUEbgABN.ia08R9mccGYGn66qGutNir27qWbg8iY+7
  HDRx.Hjf+OPHCQgPdpQHoxhBlwB+QF4cbkthlCRk4REnfeKScs3ZwaugWBbj
  .PS+.qDPAkZkgPlY5oPS4By2A5aTLFv9pounjsgpnZVF3x27pqtBrRpJnZaa
  C3WxTkfUJYA.BzR.BhIy.ehquw7dSoJCsrlATLckR.nhLPNWvVwL+Vp1LHL.
  SjMG.tRaG7OxT5R2c8Hx9B8.wLCxVaGI6qnpj45Ug84kL+6YIM8CqUxJyycF
  7bqsBRULGvwfWyRMyovElat7NvqoejaLm4f+fkmyKuVTHy3q3ldhB.WtQY6Z
  x0BSOeSpTqA+FW+Yy3SyybH3sFy8p0RVCmaMpTyX6HdDZ2JsPbfSogbBMueH
  JLd6RMBdfRMzPjZvimuWIK2XgFA.ZmtfKoh0Sm88qc6OF4bDQ3P6kEtF6xej
  .OkjD4H5OllyS+.3FlhY0so4xRlWqyrXErQpt+2rsnXgQNZHZgmMVzEofW7T
  S4zORQtgIdDbRHrObRzSMNofUVZVcbKbhQZrSOo934TqRHIN2ncr7BF8TKR1
  tHDqL.PejLRRPKMR.pKFAkbtDa+UOvsYsIFH0DYsTCjqZ66T1CmGeDILLpSm
  myk0SdkOKh5LUr4GbWwRYdW7fm.BvDmzHnSdH3biGpSbxxDNJoGDAD1ChH7L
  I0DaloOTBLvkO7zPs5HJnKNoGAXbol5eytUhfyiSfnjE1uAq+Fp0a+wygGwR
  q3ZI8.psJpkpJnyPzwmXBj7Sh.+bNvVZxlcKAm0OYHIxcIjzEKdRChgO5UMf
  LkMPNN0MfiS7Ev6TYQct.F5IWcCZ4504rGsiVswGWWSYyma01QcZgmL+f+sf
  oU18Hn6o6dXkMkFF14TL9rIAWE+6wvGV.p.TPqz3HK5L+VxYxl4UmBKEjr.B
  6zinuKI3C+D2Y7azIM6N7QL6t+jQyZxymK1ToAKqVsxjlGyjz2c1kTK3180h
  kJEYkacWpv6lyp2VJTjWK47wHA6fyBOWxH9pUf6jUtZkLpNKW.9EeUBH3ymY
  XSQlaqGrkQMGzp20adYSmIOGjIABo1xZyAWJtCX9tg6+HMuhMCPyx76ao+Us
  UxmzUE79H8d2ZB1m1ztbnOa1mGeAq0awyK8a9UqBUc6pZolpzurTK232e5gp
  aInVw8QIIcpaiNSJfY4Z+92Cs+Mc+mgg2cEsvGlLY6V+1kMuioxnB5VM+fsY
  9vSu4WI1PMBGXye6KXvNuzmZTh7U9h5j6vvASdngPdgOFxycNL6ia1axUMmT
  JIzebXcQCn3SKMf+4QCMmOZung+6xBCPLfwO8ngcEI52YJ1y7mx3CN9xKUYU
  bg7Y1yXjlKW6SrZnguQdsSfOSSDItqv2jwJFjavc1vO7OigyBr2+gDYorRk1
  HXZpVFfu2FxXkZtfp4RQqNkX5y2sya3YYL2iavWAOaizH+pw.Ibg8f1I9h3Z
  2B79sNeOHvBOtfEalWsvyu0KMf015.AaROvZ7vv5AhnndfHLbTgjcCK1KlHv
  gOk5B26OqrXjcJ005.QqCHn8fVTxnxfj93SfQiJlv8YV0VT9fVUwOOhSV3uD
  eeqCUClbBPa.j3vWDoMZssNTzRNEnE6gYPXazZaMF921syaLWyAeBXvCESA8
  ASi6Zyw8.RQi65J8ZsNx3ho93OhGWENtWpowepae4YhCFeLErOLENtXJrOSc
  iadi39rf4hwc8xdhHz3gn3dBI7iDRlFe8huAfIZhq
  -----------end_max5_patcher-----------

*/


text:
/*
  Reading a serial ASCII-encoded string.

  This sketch demonstrates the Serial parseInt() function.
  It looks for an ASCII string of comma-separated values.
  It parses them into ints, and uses those to fade an RGB LED.

  Circuit: Common-Cathode RGB LED wired like so:
  - red anode: digital pin 3 through 220 ohm resistor
  - green anode: digital pin 5 through 220 ohm resistor
  - blue anode: digital pin 6 through 220 ohm resistor
  - cathode: GND

  created 13 Apr 2012
  by Tom Igoe
  modified 14 Mar 2016
  by Arturo Guadalupi

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/ReadASCIIString
*/

// pins for the LEDs:
const int redPin = 3;
const int greenPin = 5;
const int bluePin = 6;

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // make the pins outputs:
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int red = Serial.parseInt();
    // do it again:
    int green = Serial.parseInt();
    // do it again:
    int blue = Serial.parseInt();

    // look for the newline. That's the end of your sentence:
    if (Serial.read() == '\n') {
      // constrain the values to 0 - 255 and invert
      // if you're using a common-cathode LED, just use "constrain(color, 0, 255);"
      red = 255 - constrain(red, 0, 255);
      green = 255 - constrain(green, 0, 255);
      blue = 255 - constrain(blue, 0, 255);

      // fade the red, green, and blue legs of the LED:
      analogWrite(redPin, red);
      analogWrite(greenPin, green);
      analogWrite(bluePin, blue);

      // print the three numbers in one string as hexadecimal:
      Serial.print(red, HEX);
      Serial.print(green, HEX);
      Serial.println(blue, HEX);
    }
  }
}


text:
/*
  MIDI note player

  This sketch shows how to use the serial transmit pin (pin 1) to send MIDI note data.
  If this circuit is connected to a MIDI synth, it will play the notes
  F#-0 (0x1E) to F#-5 (0x5A) in sequence.

  The circuit:
  - digital in 1 connected to MIDI jack pin 5
  - MIDI jack pin 2 connected to ground
  - MIDI jack pin 4 connected to +5V through 220 ohm resistor
  - Attach a MIDI cable to the jack, then to a MIDI synth, and play music.

  created 13 Jun 2006
  modified 13 Aug 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Midi
*/

void setup() {
  // Set MIDI baud rate:
  Serial.begin(31250);
}

void loop() {
  // play notes from F#-0 (0x1E) to F#-5 (0x5A):
  for (int note = 0x1E; note < 0x5A; note++) {
    //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
    noteOn(0x90, note, 0x45);
    delay(100);
    //Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
    noteOn(0x90, note, 0x00);
    delay(100);
  }
}

// plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that
// data values are less than 127:
void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}


text:
/*
  Graph

  A simple example of communication from the Arduino board to the computer: The
  value of analog input 0 is sent out the serial port. We call this "serial"
  communication because the connection appears to both the Arduino and the
  computer as a serial port, even though it may actually use a USB cable. Bytes
  are sent one after another (serially) from the Arduino to the computer.

  You can use the Arduino Serial Monitor to view the sent data, or it can be
  read by Processing, PD, Max/MSP, or any other program capable of reading data
  from a serial port. The Processing code below graphs the data received so you
  can see the value of the analog input changing over time.

  The circuit:
  - any analog input sensor attached to analog in pin 0

  created 2006
  by David A. Mellis
  modified 9 Apr 2012
  by Tom Igoe and Scott Fitzgerald

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Graph
*/

void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
}

void loop() {
  // send the value of analog input 0:
  Serial.println(analogRead(A0));
  // wait a bit for the analog-to-digital converter to stabilize after the last
  // reading:
  delay(2);
}

/* Processing code for this example

  // Graphing sketch

  // This program takes ASCII-encoded strings from the serial port at 9600 baud
  // and graphs them. It expects values in the range 0 to 1023, followed by a
  // newline, or newline and carriage return

  // created 20 Apr 2005
  // updated 24 Nov 2015
  // by Tom Igoe
  // This example code is in the public domain.

  import processing.serial.*;

  Serial myPort;        // The serial port
  int xPos = 1;         // horizontal position of the graph
  float inByte = 0;

  void setup () {
    // set the window size:
    size(400, 300);

    // List all the available serial ports
    // if using Processing 2.1 or later, use Serial.printArray()
    println(Serial.list());

    // I know that the first port in the serial list on my Mac is always my
    // Arduino, so I open Serial.list()[0].
    // Open whatever port is the one you're using.
    myPort = new Serial(this, Serial.list()[0], 9600);

    // don't generate a serialEvent() unless you get a newline character:
    myPort.bufferUntil('\n');

    // set initial background:
    background(0);
  }

  void draw () {
    // draw the line:
    stroke(127, 34, 255);
    line(xPos, height, xPos, height - inByte);

    // at the edge of the screen, go back to the beginning:
    if (xPos >= width) {
      xPos = 0;
      background(0);
    } else {
      // increment the horizontal position:
      xPos++;
    }
  }

  void serialEvent (Serial myPort) {
    // get the ASCII string:
    String inString = myPort.readStringUntil('\n');

    if (inString != null) {
      // trim off any whitespace:
      inString = trim(inString);
      // convert to an int and map to the screen height:
      inByte = float(inString);
      println(inByte);
      inByte = map(inByte, 0, 1023, 0, height);
    }
  }

*/

/* Max/MSP v5 patch for this example

  ----------begin_max5_patcher----------
  1591.3oc0YszbaaCD9r7uBL5RalQUAO3CvdyS5zVenWZxs5NcfHgjPCIfJIT
  RTxj+6AOHkoTDooroUs0AQPR73a+1cwtK3WtZxzEpOwqlB9YveAlL4KWMYh6
  Q1GLo99ISKXeJMmU451zTUQAWpmNy+NM+SZ2y+sR1l02JuU9t0hJvFlNcMPy
  dOuBv.U5Rgb0LPpRpYBooM3529latArTUVvzZdFPtsXAuDrrTU.f.sBffXxL
  vGE50lIHkUVJXq3fRtdaoDvjYfbgjujaFJSCzq4.tLaN.bi1tJefWpqbO0uz
  1IjIABoluxrJ1guxh2JfPO2B5zRNyBCLDFcqbwNvuv9fHCb8bvevyyEU2JKT
  YhkBSWPAfq2TZ6YhqmuMUo0feUn+rYpY4YtY+cFw3lUJdCMYAapZqzwUHX8S
  crjAd+SIOU6UBAwIygy.Q1+HAA1KH6EveWOFQlitUK92ehfal9kFhUxJ3tWc
  sgpxadigWExbt1o7Ps5dk3yttivyg20W0VcSmg1G90qtx92rAZbH4ez.ruy1
  nhmaDPidE07J+5n2sg6E6oKXxUSmc20o6E3SPRDbrkXnPGUYE.i5nCNB9TxQ
  jG.G0kCTZtH88f07Rt0ZMMWUw8VvbKVAaTk6GyoraPdZff7rQTejBN54lgyv
  HE0Ft7AvIvvgvIwO23jBdUkYOuSvIFSiNcjFhiSsUBwsUCh1AgfNSBAeNDBZ
  DIDqY.f8.YjfjV1HAn9XDTxyNFYatVTkKx3kcK9GraZpI5jv7GOx+Z37Xh82
  LSKHIDmDXaESoXRngIZQDKVkpxUkMCyXCQhcCK1z.G457gi3TzMz4RFD515F
  G3bIQQwcP3SOF0zlkGhiCBQ1kOHHFFlXaEBQIQnCwv9QF1LxPZ.A4jR5cyQs
  vbvHMJsLll01We+rE2LazX6zYmCraRrsPFwKg1ANBZFY.IAihr8Ox.aH0oAL
  hB8nQVw0FSJiZeunOykbT6t3r.NP8.iL+bnwNiXuVMNJH9H9YCm89CFXPBER
  bz422p8.O4dg6kRxdyjDqRwMIHTbT3QFLskxJ8tbmQK4tm0XGeZWF7wKKtYY
  aTAF.XPNFaaQBinQMJ4QLF0aNHF0JtYuHSxoUZfZY6.UU2ejJTb8lQw8Fo5k
  Rv6e2PI+fOM71o2ecY1VgTYdCSxxUqLokuYq9jYJi6lxPgD2NIPePLB0mwbG
  YA9Rgxdiu1k5xiLlSU6JVnx6wzg3sYHwTesB8Z5D7RiGZpXyvDNJY.DQX3.H
  hvmcUN4bP1yCkhpTle2P37jtBsKrLWcMScEmltOPv22ZfAqQAdKr9HzATQwZ
  q18PrUGt6Tst2XMCRUfGuhXs6ccn23YloomMqcTiC5iMGPsHsHRWhWFlaenV
  XcqwgCQiGGJzptyS2ZMODBz6fGza0bzmXBj7+DA94bvpR01MffAlueO7HwcI
  pWCwmzJdvi9ILgflLAFmyXB6O7ML0YbD26lenmcGxjVsZUN+A6pUK7AtTrPg
  M+eRYG0qD9j4I7eEbco8Xh6WcO.or9XDC6UCiewbXHkh6xm5LiPEkzpJDRTu
  mEB44Fgz4NCtJvX.SM1vo2SlTCZGAe7GZu6ahdRyzFOhYZ+mbVVSYptBw.K1
  tboIkatIA7c1cTKD1u.honLYV04VkluHsXe0szv9pQCE9Ro3jaVB1o15pz2X
  zYoBvO5KXCAe0LCYJybE8ZODf4fV8t9qW0zYxq.YJfTosj1bv0xc.SaC0+AV
  9V9L.KKyV3SyTcRtmzi6rO.O16USvts4B5xe9EymDvebK0eMfW6+NIsNlE2m
  eqRyJ0utRq13+RjmqYKN1e.4d61jjdsauXe3.2p6jgi9hsNIv97CoyJ01xzl
  c3ZhUCtSHx3UZgjoEJYqNY+hYs5zZQVFW19L3JDYaTlMLqAAt1G2yXlnFg9a
  53L1FJVcv.cOX0dh7mCVGCLce7GFcQwDdH5Ta3nyAS0pQbHxegr+tGIZORgM
  RnMj5vGl1Fs16drnk7Tf1XOLgv1n0d2iEsCxR.eQsNOZ4FGF7whofgfI3kES
  1kCeOX5L2rifbdu0A9ae2X.V33B1Z+.Bj1FrP5iFrCYCG5EUWSG.hhunHJd.
  HJ5hhnng3h9HPj4lud02.1bxGw.
  -----------end_max5_patcher-----------

*/


text:
/*
  ASCII table

  Prints out byte values in all possible formats:
  - as raw binary values
  - as ASCII-encoded decimal, hex, octal, and binary values

  For more on ASCII, see http://www.asciitable.com and http://en.wikipedia.org/wiki/ASCII

  The circuit: No external hardware needed.

  created 2006
  by Nicholas Zambetti <http://www.zambetti.com>
  modified 9 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/ASCIITable
*/

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // prints title with ending line break
  Serial.println("ASCII Table ~ Character Map");
}

// first visible ASCIIcharacter '!' is number 33:
int thisByte = 33;
// you can also write ASCII characters in single quotes.
// for example, '!' is the same as 33, so you could also use this:
// int thisByte = '!';

void loop() {
  // prints value unaltered, i.e. the raw binary version of the byte.
  // The Serial Monitor interprets all bytes as ASCII, so 33, the first number,
  // will show up as '!'
  Serial.write(thisByte);

  Serial.print(", dec: ");
  // prints value as string as an ASCII-encoded decimal (base 10).
  // Decimal is the default format for Serial.print() and Serial.println(),
  // so no modifier is needed:
  Serial.print(thisByte);
  // But you can declare the modifier for decimal if you want to.
  // this also works if you uncomment it:

  // Serial.print(thisByte, DEC);

  Serial.print(", hex: ");
  // prints value as string in hexadecimal (base 16):
  Serial.print(thisByte, HEX);

  Serial.print(", oct: ");
  // prints value as string in octal (base 8);
  Serial.print(thisByte, OCT);

  Serial.print(", bin: ");
  // prints value as string in binary (base 2) also prints ending line break:
  Serial.println(thisByte, BIN);

  // if printed last visible character '~' or 126, stop:
  if (thisByte == 126) {  // you could also use if (thisByte == '~') {
    // This loop loops forever and does nothing
    while (true) {
      continue;
    }
  }
  // go on to the next character
  thisByte++;
}


text:
/*
  Dimmer

  Demonstrates sending data from the computer to the Arduino board, in this case
  to control the brightness of an LED. The data is sent in individual bytes,
  each of which ranges from 0 to 255. Arduino reads these bytes and uses them to
  set the brightness of the LED.

  The circuit:
  - LED attached from digital pin 9 to ground through 220 ohm resistor.
  - Serial connection to Processing, Max/MSP, or another serial application

  created 2006
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe and Scott Fitzgerald

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Dimmer
*/

const int ledPin = 9;  // the pin that the LED is attached to

void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
  // initialize the ledPin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  byte brightness;

  // check if data has been sent from the computer:
  if (Serial.available()) {
    // read the most recent byte (which will be from 0 to 255):
    brightness = Serial.read();
    // set the brightness of the LED:
    analogWrite(ledPin, brightness);
  }
}

/* Processing code for this example

  // Dimmer - sends bytes over a serial port

  // by David A. Mellis
  // This example code is in the public domain.

  import processing.serial.*;
  Serial port;

  void setup() {
    size(256, 150);

    println("Available serial ports:");
    // if using Processing 2.1 or later, use Serial.printArray()
    println(Serial.list());

    // Uses the first port in this list (number 0). Change this to select the port
    // corresponding to your Arduino board. The last parameter (e.g. 9600) is the
    // speed of the communication. It has to correspond to the value passed to
    // Serial.begin() in your Arduino sketch.
    port = new Serial(this, Serial.list()[0], 9600);

    // If you know the name of the port used by the Arduino board, you can specify
    // it directly like this.
    //port = new Serial(this, "COM1", 9600);
  }

  void draw() {
    // draw a gradient from black to white
    for (int i = 0; i < 256; i++) {
      stroke(i);
      line(i, 0, i, 150);
    }

    // write the current X-position of the mouse to the serial port as
    // a single byte
    port.write(mouseX);
  }

*/

/* Max/MSP v5 patch for this example

  ----------begin_max5_patcher----------
  1008.3ocuXszaiaCD9r8uhA5rqAeHIa0aAMaAVf1S6hdoYQAsDiL6JQZHQ2M
  YWr+2KeX4vjnjXKKkKhhiGQ9MeyCNz+X9rnMp63sQvuB+MLa1OlOalSjUvrC
  ymEUytKuh05TKJWUWyk5nE9eSyuS6jesvHu4F4MxOuUzB6X57sPKWVzBLXiP
  xZtGj6q2vafaaT0.BzJfjj.p8ZPukazsQvpfcpFs8mXR3plh8BoBxURIOWyK
  rxspZ0YI.eTCEh5Vqp+wGtFXZMKe6CZc3yWZwTdCmYW.BBkdiby8v0r+ST.W
  sD9SdUkn8FYspPbqvnBNFtZWiUyLmleJWo0vuKzeuj2vpJLaWA7YiE7wREui
  FpDFDp1KcbAFcP5sJoVxp4NB5Jq40ougIDxJt1wo3GDZHiNocKhiIExx+owv
  AdOEAksDs.RRrOoww1Arc.9RvN2J9tamwjkcqknvAE0l+8WnjHqreNet8whK
  z6mukIK4d+Xknv3jstvJs8EirMMhxsZIusET25jXbX8xczIl5xPVxhPcTGFu
  xNDu9rXtUCg37g9Q8Yc+EuofIYmg8QdkPCrOnXsaHwYs3rWx9PGsO+pqueG2
  uNQBqWFh1X7qQG+3.VHcHrfO1nyR2TlqpTM9MDsLKNCQVz6KO.+Sfc5j1Ykj
  jzkn2jwNDRP7LVb3d9LtoWBAOnvB92Le6yRmZ4UF7YpQhiFi7A5Ka8zXhKdA
  4r9TRGG7V4COiSbAJKdXrWNhhF0hNUh7uBa4Mba0l7JUK+omjDMwkSn95Izr
  TOwkdp7W.oPRmNRQsiKeu4j3CkfVgt.NYPEYqMGvvJ48vIlPiyzrIuZskWIS
  xGJPcmPiWOfLodybH3wjPbMYwlbFIMNHPHFOtLBNaLSa9sGk1TxMzCX5KTa6
  WIH2ocxSdngM0QPqFRxyPHFsprrhGc9Gy9xoBjz0NWdR2yW9DUa2F85jG2v9
  FgTO4Q8qiC7fzzQNpmNpsY3BrYPVJBMJQ1uVmoItRhw9NrVGO3NMNzYZ+zS7
  3WTvTOnUydG5kHMKLqAOjTe7fN2bGSxOZDkMrBrGQ9J1gONBEy0k4gVo8qHc
  cxmfxVihWz6a3yqY9NazzUYkua9UnynadOtogW.JfsVGRVNEbWF8I+eHtcwJ
  +wLXqZeSdWLo+FQF6731Tva0BISKTx.cLwmgJsUTTvkg1YsnXmxDge.CDR7x
  D6YmX6fMznaF7kdczmJXwm.XSOOrdoHhNA7GMiZYLZZR.+4lconMaJP6JOZ8
  ftCs1YWHZI3o.sIXezX5ihMSuXzZtk3ai1mXRSczoCS32hAydeyXNEu5SHyS
  xqZqbd3ZLdera1iPqYxOm++v7SUSz
  -----------end_max5_patcher-----------

*/