diff --git a/.gitignore b/.gitignore
index 8c7a9389..7da61ffc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,17 +1,13 @@
 .pioenvs
+.pio
 .clang_complete
 .gcc-flags.json
 .piolibdeps
-src/main.cpp
 /debug
-lib
 .travis.yml
 !/.travis.yml
-platformio.ini
 /TODO.txt
-/classes.odg
 .gitignore
 !/.gitignore
 *.odg
-examples/clickEncoder
-examples/screenNav
+*.ghc
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..3b482c66
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "parts"]
+	path = parts
+	url = https://github.com/neu-rah/parts
+[submodule "tinyTimeUtils"]
+	path = tinyTimeUtils
+	url = https://github.com/neu-rah/tinyTimeUtils
diff --git a/.project b/.project
new file mode 100644
index 00000000..58d95dc3
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ArduinoMenu</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 9e869507..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,70 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/latest/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/latest/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/latest/userguide/cmd_ci.html >
-#
-#
-language: python
-python:
-   - "2.7"
-
-sudo: false
-cache:
-   directories:
-       - "~/.platformio"
-
-env:
-   - PLATFORMIO_CI_SRC=examples/Blink/Blink/Blink.ino
-   - PLATFORMIO_CI_SRC=examples/Serial/serialio/serialio/serialio.ino
-   # - PLATFORMIO_CI_SRC=examples/Serial/ansiSerial/ansiSerial/ansiSerial.ino
-   - PLATFORMIO_CI_SRC=examples/codeCtrl/codeCtrl/codeCtrl.ino
-   - PLATFORMIO_CI_SRC=examples/adafruitGfx/lcdMono/lcdMono/lcdMono.ino
-   - PLATFORMIO_CI_SRC=examples/adafruitGfx/tft/tft/tft.ino
-   - PLATFORMIO_CI_SRC=examples/U8GLib/U8GLib/U8GLib.ino
-
-install:
-   - pip install -U platformio
-
-   - wget https://github.com/scottdky/Streaming/archive/master.zip -O /tmp/Streaming.zip
-   - unzip /tmp/Streaming.zip -d /tmp/
-
-  #  - wget https://github.com/nettigo/Assert4a/archive/master.zip -O /tmp/Assert4a.zip
-  #  - unzip /tmp/Assert4a.zip -d /tmp/
-
-   - wget https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip -O /tmp/Adafruit-GFX-Library-master.zip
-   - unzip /tmp/Adafruit-GFX-Library-master.zip -d /tmp/
-
-   - wget https://github.com/neu-rah/PCINT/archive/master.zip -O /tmp/PCINT-master.zip
-   - unzip /tmp/PCINT-master.zip -d /tmp/
-
-   - wget https://github.com/olikraus/U8glib_Arduino/archive/master.zip -O /tmp/U8glib_Arduino-master.zip
-   - unzip /tmp/U8glib_Arduino-master.zip -d /tmp/
-
-   - wget https://github.com/neu-rah/AnsiStream/archive/master.zip -O /tmp/AnsiStream-master.zip
-   - unzip /tmp/AnsiStream-master.zip -d /tmp/
-
-   - wget https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/NewliquidCrystal_1.3.4.zip -O /tmp/NewliquidCrystal_1.3.4.zip
-   - unzip /tmp/NewliquidCrystal_1.3.4.zip -d /tmp/
-
-   - wget https://github.com/adafruit/Adafruit-PCD8544-Nokia-5110-LCD-library/archive/master.zip -O /tmp/Adafruit-PCD8544-Nokia-5110-LCD-library-master.zip
-   - unzip /tmp/Adafruit-PCD8544-Nokia-5110-LCD-library-master.zip -d /tmp/
-
-   - wget https://github.com/adafruit/Adafruit-ST7735-Library/archive/master.zip -O /tmp/Adafruit-ST7735-Library-master.zip
-   - unzip /tmp/Adafruit-ST7735-Library-master.zip -d /tmp/
-
-   # - wget https://github.com/PaulStoffregen/SD/archive/master.zip -O /tmp/SD-master.zip
-   # - unzip /tmp/SD-master.zip -d /tmp/
-
-script:
-  #  - platformio ci --lib="."  --lib="/tmp/SD-master"  --board=nanoatmega328 --board=teensy31 
-   - platformio ci --lib="." --lib="/tmp/Streaming-master" --lib="/tmp/Adafruit-GFX-Library-master" --lib="/tmp/PCINT-master" --lib="/tmp/U8glib_Arduino-master" --lib="/tmp/AnsiStream-master" --lib="/tmp/NewliquidCrystal" --lib="/tmp/Adafruit-PCD8544-Nokia-5110-LCD-library-master" --lib="/tmp/Adafruit-ST7735-Library-master" --board=nanoatmega328 --board=teensy31 --board=due
diff --git a/AM5.code-workspace b/AM5.code-workspace
new file mode 100644
index 00000000..dc52a093
--- /dev/null
+++ b/AM5.code-workspace
@@ -0,0 +1,31 @@
+{
+	"folders": [
+		{
+			"name": "ArduinoMenu",
+			"path": "."
+		},
+		{
+			"path": "examples/atmega"
+		},
+		{
+			"path": "examples/console"
+		}
+	],
+	"settings": {
+		"files.associations": {
+			"ostream": "cpp",
+			"*.tcc": "cpp",
+			"limits": "cpp",
+			"typeinfo": "cpp",
+			"cmath": "cpp",
+			"array": "cpp",
+			"chrono": "cpp",
+			"complex": "cpp",
+			"optional": "cpp",
+			"algorithm": "cpp",
+			"numeric": "cpp",
+			"streambuf": "cpp",
+			"thread": "cpp"
+		}
+	}
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 8f65f5df..00000000
--- a/LICENSE
+++ /dev/null
@@ -1,437 +0,0 @@
-Attribution-NonCommercial-ShareAlike 4.0 International
-
-=======================================================================
-
-Creative Commons Corporation ("Creative Commons") is not a law firm and
-does not provide legal services or legal advice. Distribution of
-Creative Commons public licenses does not create a lawyer-client or
-other relationship. Creative Commons makes its licenses and related
-information available on an "as-is" basis. Creative Commons gives no
-warranties regarding its licenses, any material licensed under their
-terms and conditions, or any related information. Creative Commons
-disclaims all liability for damages resulting from their use to the
-fullest extent possible.
-
-Using Creative Commons Public Licenses
-
-Creative Commons public licenses provide a standard set of terms and
-conditions that creators and other rights holders may use to share
-original works of authorship and other material subject to copyright
-and certain other rights specified in the public license below. The
-following considerations are for informational purposes only, are not
-exhaustive, and do not form part of our licenses.
-
-     Considerations for licensors: Our public licenses are
-     intended for use by those authorized to give the public
-     permission to use material in ways otherwise restricted by
-     copyright and certain other rights. Our licenses are
-     irrevocable. Licensors should read and understand the terms
-     and conditions of the license they choose before applying it.
-     Licensors should also secure all rights necessary before
-     applying our licenses so that the public can reuse the
-     material as expected. Licensors should clearly mark any
-     material not subject to the license. This includes other CC-
-     licensed material, or material used under an exception or
-     limitation to copyright. More considerations for licensors:
-	wiki.creativecommons.org/Considerations_for_licensors
-
-     Considerations for the public: By using one of our public
-     licenses, a licensor grants the public permission to use the
-     licensed material under specified terms and conditions. If
-     the licensor's permission is not necessary for any reason--for
-     example, because of any applicable exception or limitation to
-     copyright--then that use is not regulated by the license. Our
-     licenses grant only permissions under copyright and certain
-     other rights that a licensor has authority to grant. Use of
-     the licensed material may still be restricted for other
-     reasons, including because others have copyright or other
-     rights in the material. A licensor may make special requests,
-     such as asking that all changes be marked or described.
-     Although not required by our licenses, you are encouraged to
-     respect those requests where reasonable. More considerations
-     for the public: 
-	wiki.creativecommons.org/Considerations_for_licensees
-
-=======================================================================
-
-Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
-Public License
-
-By exercising the Licensed Rights (defined below), You accept and agree
-to be bound by the terms and conditions of this Creative Commons
-Attribution-NonCommercial-ShareAlike 4.0 International Public License
-("Public License"). To the extent this Public License may be
-interpreted as a contract, You are granted the Licensed Rights in
-consideration of Your acceptance of these terms and conditions, and the
-Licensor grants You such rights in consideration of benefits the
-Licensor receives from making the Licensed Material available under
-these terms and conditions.
-
-
-Section 1 -- Definitions.
-
-  a. Adapted Material means material subject to Copyright and Similar
-     Rights that is derived from or based upon the Licensed Material
-     and in which the Licensed Material is translated, altered,
-     arranged, transformed, or otherwise modified in a manner requiring
-     permission under the Copyright and Similar Rights held by the
-     Licensor. For purposes of this Public License, where the Licensed
-     Material is a musical work, performance, or sound recording,
-     Adapted Material is always produced where the Licensed Material is
-     synched in timed relation with a moving image.
-
-  b. Adapter's License means the license You apply to Your Copyright
-     and Similar Rights in Your contributions to Adapted Material in
-     accordance with the terms and conditions of this Public License.
-
-  c. BY-NC-SA Compatible License means a license listed at
-     creativecommons.org/compatiblelicenses, approved by Creative
-     Commons as essentially the equivalent of this Public License.
-
-  d. Copyright and Similar Rights means copyright and/or similar rights
-     closely related to copyright including, without limitation,
-     performance, broadcast, sound recording, and Sui Generis Database
-     Rights, without regard to how the rights are labeled or
-     categorized. For purposes of this Public License, the rights
-     specified in Section 2(b)(1)-(2) are not Copyright and Similar
-     Rights.
-
-  e. Effective Technological Measures means those measures that, in the
-     absence of proper authority, may not be circumvented under laws
-     fulfilling obligations under Article 11 of the WIPO Copyright
-     Treaty adopted on December 20, 1996, and/or similar international
-     agreements.
-
-  f. Exceptions and Limitations means fair use, fair dealing, and/or
-     any other exception or limitation to Copyright and Similar Rights
-     that applies to Your use of the Licensed Material.
-
-  g. License Elements means the license attributes listed in the name
-     of a Creative Commons Public License. The License Elements of this
-     Public License are Attribution, NonCommercial, and ShareAlike.
-
-  h. Licensed Material means the artistic or literary work, database,
-     or other material to which the Licensor applied this Public
-     License.
-
-  i. Licensed Rights means the rights granted to You subject to the
-     terms and conditions of this Public License, which are limited to
-     all Copyright and Similar Rights that apply to Your use of the
-     Licensed Material and that the Licensor has authority to license.
-
-  j. Licensor means the individual(s) or entity(ies) granting rights
-     under this Public License.
-
-  k. NonCommercial means not primarily intended for or directed towards
-     commercial advantage or monetary compensation. For purposes of
-     this Public License, the exchange of the Licensed Material for
-     other material subject to Copyright and Similar Rights by digital
-     file-sharing or similar means is NonCommercial provided there is
-     no payment of monetary compensation in connection with the
-     exchange.
-
-  l. Share means to provide material to the public by any means or
-     process that requires permission under the Licensed Rights, such
-     as reproduction, public display, public performance, distribution,
-     dissemination, communication, or importation, and to make material
-     available to the public including in ways that members of the
-     public may access the material from a place and at a time
-     individually chosen by them.
-
-  m. Sui Generis Database Rights means rights other than copyright
-     resulting from Directive 96/9/EC of the European Parliament and of
-     the Council of 11 March 1996 on the legal protection of databases,
-     as amended and/or succeeded, as well as other essentially
-     equivalent rights anywhere in the world.
-
-  n. You means the individual or entity exercising the Licensed Rights
-     under this Public License. Your has a corresponding meaning.
-
-
-Section 2 -- Scope.
-
-  a. License grant.
-
-       1. Subject to the terms and conditions of this Public License,
-          the Licensor hereby grants You a worldwide, royalty-free,
-          non-sublicensable, non-exclusive, irrevocable license to
-          exercise the Licensed Rights in the Licensed Material to:
-
-            a. reproduce and Share the Licensed Material, in whole or
-               in part, for NonCommercial purposes only; and
-
-            b. produce, reproduce, and Share Adapted Material for
-               NonCommercial purposes only.
-
-       2. Exceptions and Limitations. For the avoidance of doubt, where
-          Exceptions and Limitations apply to Your use, this Public
-          License does not apply, and You do not need to comply with
-          its terms and conditions.
-
-       3. Term. The term of this Public License is specified in Section
-          6(a).
-
-       4. Media and formats; technical modifications allowed. The
-          Licensor authorizes You to exercise the Licensed Rights in
-          all media and formats whether now known or hereafter created,
-          and to make technical modifications necessary to do so. The
-          Licensor waives and/or agrees not to assert any right or
-          authority to forbid You from making technical modifications
-          necessary to exercise the Licensed Rights, including
-          technical modifications necessary to circumvent Effective
-          Technological Measures. For purposes of this Public License,
-          simply making modifications authorized by this Section 2(a)
-          (4) never produces Adapted Material.
-
-       5. Downstream recipients.
-
-            a. Offer from the Licensor -- Licensed Material. Every
-               recipient of the Licensed Material automatically
-               receives an offer from the Licensor to exercise the
-               Licensed Rights under the terms and conditions of this
-               Public License.
-
-            b. Additional offer from the Licensor -- Adapted Material.
-               Every recipient of Adapted Material from You
-               automatically receives an offer from the Licensor to
-               exercise the Licensed Rights in the Adapted Material
-               under the conditions of the Adapter's License You apply.
-
-            c. No downstream restrictions. You may not offer or impose
-               any additional or different terms or conditions on, or
-               apply any Effective Technological Measures to, the
-               Licensed Material if doing so restricts exercise of the
-               Licensed Rights by any recipient of the Licensed
-               Material.
-
-       6. No endorsement. Nothing in this Public License constitutes or
-          may be construed as permission to assert or imply that You
-          are, or that Your use of the Licensed Material is, connected
-          with, or sponsored, endorsed, or granted official status by,
-          the Licensor or others designated to receive attribution as
-          provided in Section 3(a)(1)(A)(i).
-
-  b. Other rights.
-
-       1. Moral rights, such as the right of integrity, are not
-          licensed under this Public License, nor are publicity,
-          privacy, and/or other similar personality rights; however, to
-          the extent possible, the Licensor waives and/or agrees not to
-          assert any such rights held by the Licensor to the limited
-          extent necessary to allow You to exercise the Licensed
-          Rights, but not otherwise.
-
-       2. Patent and trademark rights are not licensed under this
-          Public License.
-
-       3. To the extent possible, the Licensor waives any right to
-          collect royalties from You for the exercise of the Licensed
-          Rights, whether directly or through a collecting society
-          under any voluntary or waivable statutory or compulsory
-          licensing scheme. In all other cases the Licensor expressly
-          reserves any right to collect such royalties, including when
-          the Licensed Material is used other than for NonCommercial
-          purposes.
-
-
-Section 3 -- License Conditions.
-
-Your exercise of the Licensed Rights is expressly made subject to the
-following conditions.
-
-  a. Attribution.
-
-       1. If You Share the Licensed Material (including in modified
-          form), You must:
-
-            a. retain the following if it is supplied by the Licensor
-               with the Licensed Material:
-
-                 i. identification of the creator(s) of the Licensed
-                    Material and any others designated to receive
-                    attribution, in any reasonable manner requested by
-                    the Licensor (including by pseudonym if
-                    designated);
-
-                ii. a copyright notice;
-
-               iii. a notice that refers to this Public License;
-
-                iv. a notice that refers to the disclaimer of
-                    warranties;
-
-                 v. a URI or hyperlink to the Licensed Material to the
-                    extent reasonably practicable;
-
-            b. indicate if You modified the Licensed Material and
-               retain an indication of any previous modifications; and
-
-            c. indicate the Licensed Material is licensed under this
-               Public License, and include the text of, or the URI or
-               hyperlink to, this Public License.
-
-       2. You may satisfy the conditions in Section 3(a)(1) in any
-          reasonable manner based on the medium, means, and context in
-          which You Share the Licensed Material. For example, it may be
-          reasonable to satisfy the conditions by providing a URI or
-          hyperlink to a resource that includes the required
-          information.
-       3. If requested by the Licensor, You must remove any of the
-          information required by Section 3(a)(1)(A) to the extent
-          reasonably practicable.
-
-  b. ShareAlike.
-
-     In addition to the conditions in Section 3(a), if You Share
-     Adapted Material You produce, the following conditions also apply.
-
-       1. The Adapter's License You apply must be a Creative Commons
-          license with the same License Elements, this version or
-          later, or a BY-NC-SA Compatible License.
-
-       2. You must include the text of, or the URI or hyperlink to, the
-          Adapter's License You apply. You may satisfy this condition
-          in any reasonable manner based on the medium, means, and
-          context in which You Share Adapted Material.
-
-       3. You may not offer or impose any additional or different terms
-          or conditions on, or apply any Effective Technological
-          Measures to, Adapted Material that restrict exercise of the
-          rights granted under the Adapter's License You apply.
-
-
-Section 4 -- Sui Generis Database Rights.
-
-Where the Licensed Rights include Sui Generis Database Rights that
-apply to Your use of the Licensed Material:
-
-  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
-     to extract, reuse, reproduce, and Share all or a substantial
-     portion of the contents of the database for NonCommercial purposes
-     only;
-
-  b. if You include all or a substantial portion of the database
-     contents in a database in which You have Sui Generis Database
-     Rights, then the database in which You have Sui Generis Database
-     Rights (but not its individual contents) is Adapted Material,
-     including for purposes of Section 3(b); and
-
-  c. You must comply with the conditions in Section 3(a) if You Share
-     all or a substantial portion of the contents of the database.
-
-For the avoidance of doubt, this Section 4 supplements and does not
-replace Your obligations under this Public License where the Licensed
-Rights include other Copyright and Similar Rights.
-
-
-Section 5 -- Disclaimer of Warranties and Limitation of Liability.
-
-  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
-     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
-     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
-     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
-     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
-     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
-     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
-     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
-     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
-     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
-
-  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
-     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
-     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
-     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
-     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
-     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
-     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
-     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
-     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
-
-  c. The disclaimer of warranties and limitation of liability provided
-     above shall be interpreted in a manner that, to the extent
-     possible, most closely approximates an absolute disclaimer and
-     waiver of all liability.
-
-
-Section 6 -- Term and Termination.
-
-  a. This Public License applies for the term of the Copyright and
-     Similar Rights licensed here. However, if You fail to comply with
-     this Public License, then Your rights under this Public License
-     terminate automatically.
-
-  b. Where Your right to use the Licensed Material has terminated under
-     Section 6(a), it reinstates:
-
-       1. automatically as of the date the violation is cured, provided
-          it is cured within 30 days of Your discovery of the
-          violation; or
-
-       2. upon express reinstatement by the Licensor.
-
-     For the avoidance of doubt, this Section 6(b) does not affect any
-     right the Licensor may have to seek remedies for Your violations
-     of this Public License.
-
-  c. For the avoidance of doubt, the Licensor may also offer the
-     Licensed Material under separate terms or conditions or stop
-     distributing the Licensed Material at any time; however, doing so
-     will not terminate this Public License.
-
-  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
-     License.
-
-
-Section 7 -- Other Terms and Conditions.
-
-  a. The Licensor shall not be bound by any additional or different
-     terms or conditions communicated by You unless expressly agreed.
-
-  b. Any arrangements, understandings, or agreements regarding the
-     Licensed Material not stated herein are separate from and
-     independent of the terms and conditions of this Public License.
-
-
-Section 8 -- Interpretation.
-
-  a. For the avoidance of doubt, this Public License does not, and
-     shall not be interpreted to, reduce, limit, restrict, or impose
-     conditions on any use of the Licensed Material that could lawfully
-     be made without permission under this Public License.
-
-  b. To the extent possible, if any provision of this Public License is
-     deemed unenforceable, it shall be automatically reformed to the
-     minimum extent necessary to make it enforceable. If the provision
-     cannot be reformed, it shall be severed from this Public License
-     without affecting the enforceability of the remaining terms and
-     conditions.
-
-  c. No term or condition of this Public License will be waived and no
-     failure to comply consented to unless expressly agreed to by the
-     Licensor.
-
-  d. Nothing in this Public License constitutes or may be interpreted
-     as a limitation upon, or waiver of, any privileges and immunities
-     that apply to the Licensor or You, including from the legal
-     processes of any jurisdiction or authority.
-
-=======================================================================
-
-Creative Commons is not a party to its public
-licenses. Notwithstanding, Creative Commons may elect to apply one of
-its public licenses to material it publishes and in those instances
-will be considered the “Licensor.” The text of the Creative Commons
-public licenses is dedicated to the public domain under the CC0 Public
-Domain Dedication. Except for the limited purpose of indicating that
-material is shared under a Creative Commons public license or as
-otherwise permitted by the Creative Commons policies published at
-creativecommons.org/policies, Creative Commons does not authorize the
-use of the trademark "Creative Commons" or any other trademark or logo
-of Creative Commons without its prior written consent including,
-without limitation, in connection with any unauthorized modifications
-to any of its public licenses or any other arrangements,
-understandings, or agreements concerning use of licensed material. For
-the avoidance of doubt, this paragraph does not form part of the
-public licenses.
-
-Creative Commons may be contacted at creativecommons.org.
diff --git a/README.md b/README.md
deleted file mode 100644
index af9a1180..00000000
--- a/README.md
+++ /dev/null
@@ -1,455 +0,0 @@
-# ArduinoMenu 4
-
-**Generic menu/interactivity system for the arduino framework**
-
-[![License: CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg)](https://spdx.org/licenses/CC-BY-NC-SA-4.0.html)
-[![Build Status](https://travis-ci.org/neu-rah/ArduinoMenu.svg?branch=master)](https://travis-ci.org/neu-rah/ArduinoMenu)
-[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/ruihfazevedo)
-[![Join Gitter](https://img.shields.io/badge/GITTER-join%20chat-green.svg)](https://gitter.im/ArduinoMenu/Lobby)
-
-## Purpose
-Full automated or user code driven navigation system.
-With this system you can define menus, submenus, input fields and other iteration objects that deal with all input/output and can call user defined handler as a result of user iteration.
-The user function can be operated as a single action called on click/enter or as a event driven function responding to focus In/Out or Enter/Esc events.
-The system is designed as a non blocking polling system, allowing concurrent task to run.
-Optionally the system can be operated in semi-automated mode, issuing navigation command from user code.
-
-See the [wiki](https://github.com/neu-rah/ArduinoMenu/wiki)
-
-## Simple Example
-```c++
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-#define MAX_DEPTH 1
-
-int timeOn=10;
-int timeOff=90;
-
-MENU(mainMenu, "Blink menu", Menu::doNothing, Menu::noEvent, Menu::wrapStyle
-  ,FIELD(timeOn,"On","ms",0,100,10,1, Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,FIELD(timeOff,"Off","ms",0,100,10,1,Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,EXIT("<Back")
-);
-
-serialIn serial(Serial);
-MENU_INPUTS(in,&serial);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-void setup() {
-  pinMode(LEDPIN, OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x");
-  Serial.println("Use keys + - * /");
-  Serial.println("to control the menu navigation");
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, HIGH);
-  delay(timeOn);
-  digitalWrite(LEDPIN, LOW);
-  delay(timeOff);
-}
-```
-
-## Features
-- Small footprint on RAM using PROGMEM on system where it is available.
-- Wide variety of input/output devices supported.
-- Easy to define menus (macros).
-- Minimalistic user code base.
-- Fields edit values hooked to existing program variables (references).
-- Editing text fields with per character validation.
-- Fields can edit numeric variables of any type (templates).
-- Reflexive fields, showing variable changes done outside the menu system.
-- Numerical field edit and range validation.
-- Enumerated fields for numeric and non-numeric types
-- Customizable (colors and cursors).
-- Able to work over Serial stream IO as a base level.
-- Supports multiple inputs and outputs in parallel.
-- static allocation of RAM, avoiding heap fragmentation, all RAM needed to define menu structure is allocated at program startup.
-- events available for menus and prompts
-- simply returns when no input available and no needed to draw.
-- lazy drawing, only draws when changed, avoiding time consumption and flicking.
-- sync/async navigation API functions
-- async navigation for stateless clients (as web)
-- web interface (experimental)
-- can be confined to a display area (numeric fields can still overflow the area, user should take account for them)
-- Tested on Arduino AVR's & ARM, Teensy, ESP8266, Esp32, nRF52, STM32
-
-## Videos
-[![IMAGE ALT TEXT](https://img.youtube.com/vi/wHv5sU-HXVI/2.jpg)](https://youtu.be/wHv5sU-HXVI "Arduino menu 2.0 fields video") [![IMAGE ALT TEXT](https://img.youtube.com/vi/W-TRCziF67g/2.jpg)](https://youtu.be/W-TRCziF67g "Arduino menu basic features video")[![IMAGE ALT TEXT](https://img.youtube.com/vi/27KEUTpCHfg/2.jpg)](https://youtu.be/27KEUTpCHfg "Arduino menu 4.x")
-
-## Plugins
-
-Plugins are particular menu combinations or item customized behaviors and/or drawing.
-
-Some plugins might be platform specific or require some hardware.
-
-- barField - displays a bar for numeric field on LCD
-- cancelField - allows to restore previous numeric value on escape.
-- SDMenu - full automated SD Card file picker, using standard Arduino SD lib.
-- SdFatMenu - full automated SD Card file picker, using standard SdFat (https://github.com/greiman/SdFat).
-
-## Applications
-
-Some applications using ArduinoMenu, (current and older versions).  
-Do you have another? please let me know on gitter or email me.
-
-**ServoBox** Servo tester & monitor  
-https://github.com/jarkman/ServoBox
-
-**PANOBOT** A Panorama robot  
-https://github.com/RobertFach/panobot
-
-**teensy-midi-looper** Microcontroller-based midi performance sequencer  
-https://github.com/newdigate/teensy-midi-looper
-
-**AmplifierControl** Automate procedure to switch on/off amplifier and band decode of Kenwood  
-https://github.com/petrlab/AmplifierControl
-
-**spna** An Arduino Single Port Network Analyzer (SPNA)  
-https://github.com/tczerwonka/spna
-
-**LRDuino** In car multi gauge system - STM32, SSD1306, MAX31856, ADXL345, ELM327  
-https://github.com/BennehBoy/LRDuino
-
-**LRDuinoTD5** In car multi gauge system - STM32, SSD1306, MAX31856, ADXL345, L9637D, TD5 ECU  
-https://github.com/BennehBoy/LRDuinoTD5
-
-**thom-radio** Internet radio build  
-https://github.com/evfool/thom-radio
-
-**MIDI_drums** 7 chanel piezo MIDI drum box with menu on LCD  
-https://github.com/Sobollion/MIDI_drums
-
-**BalancingRobot**  
-https://github.com/SLBarker/BalancingRobot
-
-**swatili** 50l water meter with valve control, lcd, buttons, rtc and hall effect pulse reader  
-https://github.com/daniel-leonard-robinson/swatili
-
-**Fielduino** hardware PWM generator using menu to select frequency and dutty.  
-https://github.com/neu-rah/Fielduino
-
-**ArduinoMultiDesktop** MultiDesktop concept for hardware devices  
-https://github.com/dontsovcmc/ArduinoMultiDesktop
-
-**SmartGreenHouse**  
-https://github.com/dontsovcmc/SmartGreenHouse/tree/master/src
-
-**console.arduino** Portable serial debug console project using ILI9341  
-https://github.com/malachib/console.arduino
-
-## Platforms
-Atmel AVR, Atmel SAM, Espressif 32, Espressif 8266, Intel ARC32, Microchip PIC32, Nordic nRF51, Nordic nRF52, ST STM32, Teensy, TI MSP430
-
-## Install
-
-**Arduino IDE** - Install using the library manager (ArduinoMenu library - Rui Azevedo)
-
-**Platformio** - http://platformio.org/lib/show/1468/ArduinoMenu%20library
-
-## IO devices
-### Output devices
-
-**Serial**
-
-https://www.arduino.cc/en/Reference/Serial
-
-- Serial monitor.
-
-**Standard arduino LCD library**
-
-https://www.arduino.cc/en/Reference/LiquidCrystal
-
-- hd44780
-
-**F Malpartida's LCDs**
-
-https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
-
-- HD44780 direct
-- HD44780 I2C
-- HD44780 SPI
-
-**Matthias Hertel PCF8574 driver**
-
-https://github.com/mathertel/LiquidCrystal_PCF8574
-
-- HD44780
-
-**Arduino TFT devices**
-
-https://www.arduino.cc/en/Guide/TFT
-
-**SSD1306Ascii**
-
-https://github.com/greiman/SSD1306Ascii
-
-- OLED Screens based on SSD1306 controller
-
-**TFT_eSPI**
-
-An Arduino IDE compatible graphics and fonts library for ESP8266 and ESP32  
-https://github.com/Bodmer/TFT_eSPI
-
-- ILI9341, ILI9163, ST7735, S6D02A1, ILI9481, ILI9486, ILI9488, HX8357D, ST7789, ILI9486
-- Waveshare 2 and 3 colour SPI ePaper displays
-
-**TFT_HX8357 driver**
-
-https://github.com/Bodmer/TFT_HX8357
-
-- HX8357B, HX8357C, ILI9481 and ILI9486
-
-**Adafruit's GFX devices**
-
-https://github.com/adafruit/Adafruit-GFX-Library
-
-- RGBmatrixPanel, 16x32 and 32x32 RGB LED matrix panels.
-- Adafruit_TFTLCD, 2.8" TFT LCD touchscreen breakout and TFT Touch Shield for Arduino.
-- Adafruit_HX8340B, 2.2" TFT Display with microSD.
-- Adafruit_ST7735, 1.8" TFT Display with microSD.
-- Adafruit_PCD8544, for the Nokia 5110/3310 monochrome LCD.
-- Adafruit-Graphic-VFD-Display-Library, for 128x64 Graphic VFD.
-- Adafruit-SSD1331-OLED-Driver-Library-for-Arduino for the 0.96" 16-bit Color OLED w/microSD Holder.
-- Adafruit_SSD1306 for the Monochrome 128x64 and 128x32 OLEDs.
-
-**UTFT devices**
-
-http://www.rinkydinkelectronics.com/library.php?id=51
-
-- ITDB02 series - ITead Studio
-- TFT01 series - ElecFreaks
-- RGB LCD - NKC Electronics.
-
-**U8glib devices**
-
-https://github.com/olikraus/U8glib_Arduino
-
-SSD1306, 128x64, SSD1306, 128x32, SSD1306, 64x48, SSD1309, 128x64, SSD1322, 256x64, SSD1325, 128x64, SSD1327, 96x96, SH1106, 128x64, UC1601, 128x32, UC1608, 240x64, UC1610, 160x104, UC1611, 240x64, UC1611, 240x128, UC1701, 128x64, UC1701, 102x64, ST7565, 128x64, ST7565, 128x32, ST7920, 128x64, ST7920, 192x32, ST7920, 202x32, LD7032, 60x32, PCD8544, 84x48, TLS8204 , 84x48, PCF8812 , 96x65, KS0108 , 128x64, T6963, 128x64, T6963, 128x128, T6963, 240x64, T6963, 240x128, SBN1661, 122x32, LC7981, 160x80, LC7981, 240x64, LC7981, 240x128, LC7981, 320x64, SSD1351, HT1632, 24x16, Flipdisk, 28x14, Virtual Screen Device
-
-**U8G2 and U8x8 devices**
-
-https://github.com/olikraus/U8g2_Arduino
-
-SSD1305 128X32_NONAME, SSD1305 128X32_NONAME, SSD1305 128X64_ADAFRUIT, SSD1305 128X64_ADAFRUIT, SSD1306 128X64_NONAME, SSD1306 128X64_VCOMH0, SSD1306 128X64_ALT0, SSD1306 128X64_NONAME, SSD1306 128X64_VCOMH0, SSD1306 128X64_ALT0, SH1106 128X64_NONAME, SH1106 128X64_VCOMH0, SH1106 128X64_WINSTAR, SH1106 128X64_NONAME, SH1106 128X64_VCOMH0, SH1106 128X64_WINSTAR, SH1106 72X40_WISE, SH1106 72X40_WISE, SH1106 64X32, SH1106 64X32, SH1107 64X128, SH1107 64X128, SH1107 SEEED_96X96, SH1107 SEEED_96X96, SH1107 128X128, SH1107 128X128, SH1122 256X64, SH1122 256X64, SSD1306 128X32_UNIVISION, SSD1306 128X32_UNIVISION, SSD1306 64X48_ER, SSD1306 64X48_ER, SSD1306 48X64_WINSTAR, SSD1306 48X64_WINSTAR, SSD1306 64X32_NONAME, SSD1306 64X32_1F, SSD1306 64X32_NONAME, SSD1306 64X32_1F, SSD1306 96X16_ER, SSD1306 96X16_ER, SSD1309 128X64_NONAME2, SSD1309 128X64_NONAME2, SSD1309 128X64_NONAME0, SSD1309 128X64_NONAME0, SSD1325 NHD_128X64, SSD1325 NHD_128X64, SSD1326 ER_256X32, SSD1326 ER_256X32, SSD1327 SEEED_96X96, SSD1327 SEEED_96X96, SSD1327 MIDAS_128X128, SSD1327 MIDAS_128X128, SSD1329 128X96_NONAME, LD7032 60X32, LD7032 60X32, ST7920 192X32, ST7920 192X32, ST7920 192X32, ST7920 128X64, ST7920 128X64, ST7920 128X64, LS013B7DH03 128X128, UC1701 EA_DOGS102, UC1701 MINI12864, PCD8544 84X48, PCF8812 96X65, HX1230 96X68, UC1604 JLX19264, UC1604 JLX19264, UC1608 ERC24064, UC1608 ERC24064, UC1608 ERC240120, UC1608 ERC240120, UC1608 240X128, UC1608 240X128, UC1638 160X128, UC1610 EA_DOGXL160, UC1610 EA_DOGXL160, UC1611 EA_DOGM240, UC1611 EA_DOGM240, UC1611 EA_DOGXL240, UC1611 EA_DOGXL240, UC1611 EW50850, UC1611 EW50850, ST7565 EA_DOGM128, ST7565 64128N, ST7565 ZOLEN_128X64, ST7565 LM6059, ST7565 LX12864, ST7565 ERC12864, ST7565 NHD_C12864, ST7565 JLX12864, ST7565 NHD_C12832, UC1601 128X32, UC1601 128X32, ST7565 EA_DOGM132, ST7567 PI_132X64, ST7567 JLX12864, ST7567 ENH_DG128064, ST7567 ENH_DG128064I, ST7588 JLX12864, ST7588 JLX12864, ST75256 JLX256128, ST75256 JLX256128, ST75256 JLX256160, ST75256 JLX256160, ST75256 JLX240160, ST75256 JLX240160, ST75256 JLX25664, ST75256 JLX25664, ST75256 JLX172104, ST75256 JLX172104, NT7534 TG12864R, IST3020 ERC19264, SBN1661 122X32, SED1520 122X32, KS0108 128X64, KS0108 ERM19264, LC7981 160X80, LC7981 160X160, LC7981 240X128, T6963 240X128, T6963 240X64, T6963 256X64, T6963 128X64, SSD1322 NHD_256X64, SSD1322 NHD_128X64, SSD1606 172X72, SSD1607 200X200, SSD1607 GD_200X200, IL3820 296X128, IL3820 V2_296X128, SED1330 240X128, RA8835 NHD_240X128, RA8835 320X240, MAX7219 32X8, A2PRINTER 384X240
-
-**UCGLib devices**
-
-https://github.com/olikraus/Ucglib_Arduino
-
-ST7735, ILI9163, ILI9325, ILI9341, ILI9486, LD50T6160, PCF8833, SEPS225, SSD1331, SSD1351, HX8352C
-
-**Serial ANSI terminal**
-
-https://github.com/neu-rah/AnsiStream
-
-- Unix terminal
-
-**Web browser**
-
-- ESP8266 (builtin)  
-
-**Web JSON**
-
-- ESP8266 (builtin)  
-
-**Websockets**
-
-- ESP8266 (builtin)  
-
-**note:** esp8266 will require a streaming library even if not using web interface, along with `#include <menuIO/esp8266Out.h>`
-
-depending on your output driver it may be one of (can install both)
-- https://github.com/neu-rah/streamFlow
-- https://github.com/scottdky/Streaming
-
-### Input devices
-
-Serial https://www.arduino.cc/en/Reference/Serial
-
-quadEncoder - Generic encoder using PCINT (builtin)  
-
-Buttons - simple digital keyboard (builtin)
-
-Generic keyboard (no PCINT) - configurable for digital or analog keyboards (builtin)
-
-ClickEncoder https://github.com/0xPIT/encoder
-
-Matrix keypad   
-http://playground.arduino.cc/Code/Keypad
-https://github.com/Nullkraft/Keypad
-
-PCF8574 based i2c matrix keypad
-https://github.com/whatnick/i2ckeypad
-
-User defined input calling menu navigation API
-
-Web browser (experimental) when using ESP devices
-
-## Dependencies
-This library depends on the following libraries:
-
-- streamFlow https://github.com/neu-rah/streamFlow (on debug mode)
-
-Depending on the type of input or output, other libraries might be needed. Essentially any library needed for your devices.
-
-## Limits
-
-- when using macros the menu is limited to 16 options (current macro limnit).
-- menus **must** have at least 2 options when built using macros.
-- maximum 127 options.
-- fast access (numeric keys) only supports 9 options (1 to 9)
-- prompts can overflow on panels with less than 4 characters width
-- menu system is character based, so choose monometric font to achieve best results, it will work with any font but the text can overflow.
-
-## Base
-
-- Character based information display.
-- Line based menu organization.
-- Stream IO + specializations.
-
-## info
-
-more info at
-
-[wiki](https://github.com/neu-rah/ArduinoMenu/wiki) pages, [issues](https://github.com/neu-rah/ArduinoMenu/issues?utf8=%E2%9C%93&q=) or [r-site.net](http://www.r-site.net/?lang=en&at=//op%5B@id=%273090%27%5D)
-
-## Errors / Sugestions
-
-Please report errors, problems or enhancement ideas, I apreciate the feedback. Thanks.
-
-On issues report please specify the input and output drivers or devices as well as target platform.
-
-## notes
-
-encoder now needs begin() to be called on setup (2.x)
-
-input is read from generic streams, included simple streams for encoders and keyboards
-	- provided encoder driver uses internal pull-ups and reverse logic
-
-multiple stream packing for input to mix encoder stream with encoder keyboard (usually 1 or 2 keys)
-
-## History
-
-### 4.0
-  - SdFat plugin and example
-  - EscControl examle
-  - support Bodmer/TFT_eSPI
-  - SDCard file picker plugin
-  - Allow virtual/dynamic data custom menus
-  - alternative key driver with explicit pin modes
-  - More examples
-  - Text edit fields with validation *
-  - Pad style menus (horizontal list)
-  - inline pad menus can input custom formats like IP/Date/Time, experimental and just for devices that can position a cursor
-  - Plugins, alternative menu items potentially device specific
-  - Allow multiple concurrent menus
-  - Support UCGLib displays
-  - Support U8x8 displays
-  - Support Arduino TFT
-  - Support PCF8574 I2C LCD
-  - Support Analog Joystick input
-  - Added input burst config option
-  - VALUEOBJ macro, user allocated values
-  - menuIn class for menu inputs (allows device field invertion) *
-  - some options have been distributed to some other classes
-  - allow dynamic menu construction (ram) even for AVR's
-
-#### * API changes
-
-##### Options
-
-<del>**invertFieldKeys** option removed, invertion is now supported by specific menuIn objects.</del>
-
-_regression: still needed to ease simple input cases._
-
-**numValueInput** moved to menuIn object
-
-**navRoot** extra options, previously on global options object
-```c++
-bool nav2D=false;//not used
-bool canExit=true;//v4.0 moved from global options
-bool useUpdateEvent=false;//if false, use enterEvent when field value is changed.
-idx_t inputBurst=1;//limit of inputs that can be processed before output
-```
-
-##### Serial input
-
-Serial is no longer accepted as an input directly, use serialIn instead
-
-##### prompt base API
-
-printTo member function changed from:
-
-```c++
-Used printTo(navRoot&,bool,menuOut&,idx_t,idx_t);
-```
-
-to
-
-```c++
-Used printTo(navRoot&,bool,menuOut&,idx_t,idx_t,idx_t=0);
-```
-
-_this should only affect customized components_
-
-inputs are now from class menuIn, derived from Stream but including flag functions for field axis inversion per input class.
-
-### 3.0
-  - complete revision of menu control system
-	- menu structure separated in ram objects and flash objects
-	- using separate navigation control objects **navNode**
-	- central navigation control object **navRoot**
-	- using event for all menu objects (focus, blur, enter, exit).
-	- multiple panels
-	- color enumeration at base level
-	- multiple output devices in parallel
-	- define exit as regular option
-	- limiting text width to prevent overflow
-
-### 2.4
-  - support for teensy (tested on 3.2)
-  - new field type SELECT
-  - reflexivity, fields reflect external changes to values
-  - store field strings to progmem
-  - automatic use of RAM on system without PROGMEM
-
-### 2.3
-
-  - action functions now need to return bool (only affects menus)
-
-  >**false** = continue menu
-  >
-  >**true** = exit menu
-
-  - Support for U8GLib screens
-  - alternative use ClickEncoder
-  - using flash memory to store menu strings and lists (PROGMEM)
-
-### 2.0
-
-  - non-blocking menu main cycle
-  - Menufields as menu prompts with associated value
-    values can be:
-      numeric withing range
-      list of values toggled on click (for small lists)
-      list of values selected as submenu (for longer lists)
-  - PCINT now supports Mega/2560 and possibly others
-
-### 1.x
-  - basic menu functionality
diff --git a/classes.odg b/classes.odg
deleted file mode 100644
index 2eb0cb9a..00000000
Binary files a/classes.odg and /dev/null differ
diff --git a/examples/Blink/.gitignore b/examples/Blink/.gitignore
deleted file mode 100644
index e05273b2..00000000
--- a/examples/Blink/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.clang_complete
-.gcc-flags.json
-.piolibdeps
\ No newline at end of file
diff --git a/examples/Blink/.travis.yml b/examples/Blink/.travis.yml
deleted file mode 100644
index 72c6e43f..00000000
--- a/examples/Blink/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/stable/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/stable/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/stable/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/Blink/Blink/Blink.ino b/examples/Blink/Blink/Blink.ino
deleted file mode 100644
index 7f09afd5..00000000
--- a/examples/Blink/Blink/Blink.ino
+++ /dev/null
@@ -1,56 +0,0 @@
-/********************
-Arduino generic menu system
-control led on/off delays
-
-Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-output: Serial
-input: Serial
-mcu: nano328p
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-#define MAX_DEPTH 1
-
-int timeOn=10;
-int timeOff=90;
-
-MENU(mainMenu, "Blink menu", Menu::doNothing, Menu::noEvent, Menu::wrapStyle
-  ,FIELD(timeOn,"On","ms",0,100,10,1, Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,FIELD(timeOff,"Off","ms",0,100,10,1,Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,EXIT("<Back")
-);
-
-serialIn serial(Serial);
-MENU_INPUTS(in,&serial);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-void setup() {
-  pinMode(LEDPIN, OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x");
-  Serial.println("Use keys + - * /");
-  Serial.println("to control the menu navigation");
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, HIGH);
-  delay(timeOn);
-  digitalWrite(LEDPIN, LOW);
-  delay(timeOff);
-}
diff --git a/examples/Blink/platformio.ini b/examples/Blink/platformio.ini
deleted file mode 100644
index d0145b94..00000000
--- a/examples/Blink/platformio.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter, extra scripting
-;   Upload options: custom port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/en/stable/projectconf.html
-
-
-[platformio]
-src_dir=Blink
-; lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -DNODEBUG
-
-; [env:uno]
-; platform = atmelavr
-; board = nanoatmega328
-; framework = arduino
-
-; [env:due]
-; platform = atmelsam
-; board = due
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -DMENU_USERAM
diff --git a/examples/Button/Button/Button.ino b/examples/Button/Button/Button.ino
deleted file mode 100644
index 7f09afd5..00000000
--- a/examples/Button/Button/Button.ino
+++ /dev/null
@@ -1,56 +0,0 @@
-/********************
-Arduino generic menu system
-control led on/off delays
-
-Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-output: Serial
-input: Serial
-mcu: nano328p
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-#define MAX_DEPTH 1
-
-int timeOn=10;
-int timeOff=90;
-
-MENU(mainMenu, "Blink menu", Menu::doNothing, Menu::noEvent, Menu::wrapStyle
-  ,FIELD(timeOn,"On","ms",0,100,10,1, Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,FIELD(timeOff,"Off","ms",0,100,10,1,Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,EXIT("<Back")
-);
-
-serialIn serial(Serial);
-MENU_INPUTS(in,&serial);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-void setup() {
-  pinMode(LEDPIN, OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x");
-  Serial.println("Use keys + - * /");
-  Serial.println("to control the menu navigation");
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, HIGH);
-  delay(timeOn);
-  digitalWrite(LEDPIN, LOW);
-  delay(timeOff);
-}
diff --git a/examples/Button/platformio.ini b/examples/Button/platformio.ini
deleted file mode 100644
index d0145b94..00000000
--- a/examples/Button/platformio.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter, extra scripting
-;   Upload options: custom port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/en/stable/projectconf.html
-
-
-[platformio]
-src_dir=Blink
-; lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -DNODEBUG
-
-; [env:uno]
-; platform = atmelavr
-; board = nanoatmega328
-; framework = arduino
-
-; [env:due]
-; platform = atmelsam
-; board = due
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -DMENU_USERAM
diff --git a/examples/Confirm/.gitignore b/examples/Confirm/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/Confirm/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/Confirm/.travis.yml b/examples/Confirm/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/Confirm/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/Confirm/Confirm/Confirm.ino b/examples/Confirm/Confirm/Confirm.ino
deleted file mode 100644
index af7635c8..00000000
--- a/examples/Confirm/Confirm/Confirm.ino
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-
-Custom sub-menu prompt used as exit confirmation
-the Exit option on this example presents only the "Exit" text
-but the submenu really as an "Exit?" text for confirmation
-choosing "Yes" will suspend the menu and possibly do other stuff
-while "Cancel" will just return to previous menu.
-
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-//customizing a menu prompt look
-class confirmExit:public menu {
-public:
-  confirmExit(constMEM menuNodeShadow& shadow):menu(shadow) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t p) override {
-    return idx<0?//idx will be -1 when printing a menu title or a valid index when printing as option
-      menu::printTo(root,sel,out,idx,len,p)://when printing title
-      out.printRaw((constText*)F("Exit"),len);//when printing as regular option
-  }
-};
-
-// this function is defined below because we need to refer
-// to the navigation system (suspending the menu)
-result systemExit();
-
-//using the customized menu class
-//note that first parameter is the class name
-altMENU(confirmExit,subMenu,"Exit?",doNothing,noEvent,wrapStyle,(Menu::_menuData|Menu::_canNav)
-  ,OP("Yes",systemExit,enterEvent)
-  ,EXIT("Cancel")
-);
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,SUBMENU(subMenu)
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-bool running=true;//lock menu if false
-
-result systemExit() {
-  Serial.println();
-  Serial.println("Terminating...");
-  //do some termiination stuff here
-  running=false;//prevents the menu from running again!
-  Serial.println("done.");
-  nav.idleOn();//suspend the menu system
-  return quit;
-}
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x custom sub-menu prompt example");Serial.flush();
-}
-
-void loop() {
-  if (running) nav.poll();
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/Confirm/platformio.ini b/examples/Confirm/platformio.ini
deleted file mode 100644
index d7211182..00000000
--- a/examples/Confirm/platformio.ini
+++ /dev/null
@@ -1,34 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=Confirm
-lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -Wno-switch
-
-; [env:esp12e]
-; platform = espressif8266
-; board = esp12e
-; framework = arduino
-; upload_speed=921600
-; build_flags = -Wno-comment -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
diff --git a/examples/CustomPrompt/.gitignore b/examples/CustomPrompt/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/CustomPrompt/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/CustomPrompt/.travis.yml b/examples/CustomPrompt/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/CustomPrompt/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/CustomPrompt/CustomPrompt/CustomPrompt.ino b/examples/CustomPrompt/CustomPrompt/CustomPrompt.ino
deleted file mode 100644
index 6e290c0c..00000000
--- a/examples/CustomPrompt/CustomPrompt/CustomPrompt.ino
+++ /dev/null
@@ -1,136 +0,0 @@
-/********************
-Aug. 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-Self update custom field
-output: Serial
-input: Serial
-www.r-site.net
-
-***/
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-
-result myLedOn() {
-  digitalWrite(LEDPIN, HIGH);
-  return proceed;
-}
-result myLedOff() {
-  digitalWrite(LEDPIN, LOW);
-  return proceed;
-}
-
-
-//customizing a prompt look!
-//by extending the prompt class
-//this prompt will count seconds and update himself on the screen.
-class altPrompt:public prompt {
-public:
-  unsigned int t=0;
-  unsigned int last=0;
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    last=t;
-    return out.printRaw(String(t).c_str(),len);
-  }
-  virtual bool changed(const navNode &nav,const menuOut& out,bool sub=true) {
-    t=millis()/1000;
-    return last!=t;
-  }
-};
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,altOP(altPrompt,"",doNothing,noEvent)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-//when menu is suspended
-//this function is called when entering or leaving suspended state
-// with idleStart and idleend cases
-//and at least once in between them (idling case)
-//it might also be called for every pool (when in suspended state, idling case)
-//for output devices that require refresh (repeated draw, idling case)
-result idle(menuOut &o, idleEvent e) {
-  o.clear();
-  switch(e) {
-    case idleStart:o.println("suspending menu!");break;
-    case idling:o.println("suspended...");break;
-    case idleEnd:o.println("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(LEDPIN,OUTPUT);
-  digitalWrite(LEDPIN,HIGH);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");Serial.flush();
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  // nav.idleOn(idle);//enter idle mode, this menu will start on idle state, press select  to enter menu
-  // nav.doInput("4");//we can also provide input from string, this will enter idle mode by exiting the menu
-
-  //this is an example of driving the menu string input
-  //this however requires a known menu state and therefor is not recomended for complicated menus
-  // see async calls instead
-  // for(int c=0;c<3;c++) {//using the menu to blink the led
-  //   nav.doInput("2");//led on
-  //   delay(1000);
-  //   nav.doInput("3");//led off
-  //   delay(1000);
-  // }
-
-  //NOTE: async is disabled now define MENU_ASYNC to activate it
-  //following code is an async navigation example
-  //its async because it does not require a known menu state
-  //because you can indicate the zero indexed option positions separated by /
-  //it also works for field by accepting the input
-  //ex: "/0/1/12" -> will select first option on main menu,
-  // then the second option (eventually a field)
-  // and finally set the field value to 12 (or select 13th position on a menu)
-  //
-  // note that this is menu position starting at zero (not accel keys)
-  // this is experimental API base for web interface
-  // for(int c=0;c<3;c++) {//using the menu to blink the led
-  //   nav.async("/1");
-  //   delay(1000);
-  //   nav.async("/2");
-  //   delay(1000);
-  // }
-
-  //there is also the possibility of navigating the menu by calling api functions
-  //this is however indicated if you have custom input devices
-  //or building a driver for a new input.
-
-  for(int c=0;c<10;c++) {//using the menu to blink the led
-    nav.doNav(navCmd(idxCmd,1));
-    nav.doNav(navCmd(enterCmd));
-    delay(300);
-    nav.doNav(navCmd(idxCmd,3));
-    nav.doNav(navCmd(enterCmd));
-    delay(300);
-  }
-
-}
-
-void loop() {
-
-  nav.poll();
-
-}
diff --git a/examples/CustomPrompt/platformio.ini b/examples/CustomPrompt/platformio.ini
deleted file mode 100644
index 23b8c14e..00000000
--- a/examples/CustomPrompt/platformio.ini
+++ /dev/null
@@ -1,44 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=CustomPrompt
-lib_dir=~/Arduino/Libraries
-
-; [env:esp12e]
-; platform=espressif8266
-; board=esp12e
-; framework=arduino
-
-; [env:uno]
-; platform = atmelavr
-; board = uno
-; framework = arduino
-
-; [env:nanoatmega328]
-; platform = atmelavr
-; board = nanoatmega328
-; framework = arduino
-; upload_port=/dev/ttyUSB*
-; upload_flags=-V
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -Wno-switch -lstdc++
-
-[env:esp12e]
-platform = espressif8266
-board = esp12e
-framework = arduino
-upload_speed=921600
-build_flags = -Wno-comment -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
diff --git a/examples/LCDs/LiquidCrystal/LiquidCrystal/LiquidCrystal.ino b/examples/LCDs/LiquidCrystal/LiquidCrystal/LiquidCrystal.ino
deleted file mode 100644
index e9fe9fc1..00000000
--- a/examples/LCDs/LiquidCrystal/LiquidCrystal/LiquidCrystal.ino
+++ /dev/null
@@ -1,212 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu output to standard arduino LCD (LiquidCrystal)
-output: LCD
-input: encoder and Serial
-www.r-site.net
-***/
-
-#include <Wire.h>
-#include <menu.h>
-#include <menuIO/liquidCrystalOut.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/encoderIn.h>
-#include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-
-using namespace Menu;
-
-// LCD /////////////////////////////////////////
-#define RS 8
-#define RW 3
-#define EN 9
-LiquidCrystal lcd(RS, RW, EN, 4, 5, 6, 7);
-
-// Encoder /////////////////////////////////////
-#define encA A2
-#define encB A1
-//this encoder has a button here
-#define encBtn A3
-
-encoderIn<encA,encB> encoder;//simple quad encoder driver
-encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-
-//a keyboard with only one key as the encoder button
-keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-keyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-//input from the encoder + encoder button + serial
-serialIn serial(Serial);
-menuIn* inputsList[]={&encStream,&encButton,&serial};
-chainStream<3> in(inputsList);//3 is the number of inputs
-
-#define LEDPIN 13
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action1 event: ");
-  Serial.print(e);
-  Serial.println(", proceed menu");
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action2 event: ");
-  Serial.print(e);
-  Serial.print(", quiting menu.");
-  Serial.flush();
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-/*extern menu mainMenu;
-TOGGLE((mainMenu[1].enabled),togOp,"Op 2:",doNothing,noEvent,noStyle
-  ,VALUE("Enabled",enabledStatus,doNothing,noEvent)
-  ,VALUE("disabled",disabledStatus,doNothing,noEvent)
-);*/
-
-// char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-// char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-// char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  //,SUBMENU(togOp)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  // ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-//const panel panels[] MEMMODE={{0,0,16,2}};
-//navNode* nodes[sizeof(panels)/sizeof(panel)];
-//panelsList pList(panels,nodes,1);
-
-#define MAX_DEPTH 2
-/*idx_t tops[MAX_DEPTH];
-liquidCrystalOut outLCD(lcd,tops,pList);//output device for LCD
-menuOut* constMEM outputs[] MEMMODE={&outLCD};//list of output devices
-outputsList out(outputs,1);//outputs list with 2 outputs*/
-
-MENU_OUTPUTS(out, MAX_DEPTH
-  ,LIQUIDCRYSTAL_OUT(lcd,{0,0,16,2})
-  ,NONE
-);
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);//the navigation root object
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("[select] to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-result idle(menuOut& o,idleEvent e) {
-  switch(e) {
-    case idleStart:o.print("suspending menu!");break;
-    case idling:o.print("suspended...");break;
-    case idleEnd:o.print("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(encBtn,INPUT_PULLUP);
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Arduino Menu Library");Serial.flush();
-  encoder.begin();
-  lcd.begin(16,2);
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  mainMenu[1].enabled=disabledStatus;
-  nav.showTitle=false;
-  lcd.setCursor(0, 0);
-  lcd.print("Menu 4.x LCD");
-  lcd.setCursor(0, 1);
-  lcd.print("r-site.net");
-  delay(2000);
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay as if other tasks are running
-}
diff --git a/examples/LCDs/Malpartida/I2C/I2C/I2C.ino b/examples/LCDs/Malpartida/I2C/I2C/I2C.ino
deleted file mode 100644
index 3bd8c95f..00000000
--- a/examples/LCDs/Malpartida/I2C/I2C/I2C.ino
+++ /dev/null
@@ -1,218 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Arduino generic menu system
-Arduino menu on I2C LCD example
-http://www.r-site.net/?at=//op%5B%40id=%273090%27%5D
-
-Sep.2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-LCD library:
-https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
-http://playground.arduino.cc/Code/LCD3wires
-*/
-#ifndef ARDUINO_SAM_DUE
-
-  #include <Wire.h>
-  #include <LiquidCrystal_I2C.h>//F. Malpartida LCD's driver
-  #include <menu.h>//menu macros and objects
-  #include <menuIO/lcdOut.h>//malpartidas lcd menu output
-  #include <menuIO/serialIn.h>//Serial input
-  #include <menuIO/encoderIn.h>//quadrature encoder driver and fake stream
-  #include <menuIO/keyIn.h>//keyboard driver and fake stream (for the encoder button)
-  #include <menuIO/chainStream.h>// concatenate multiple input streams (this allows adding a button to the encoder)
-
-  using namespace Menu;
-
-  //LiquidCrystal_I2C lcd(0x27);//, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
-  LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address and pinout
-
-  // Encoder /////////////////////////////////////
-  #define encA 2
-  #define encB 3
-  //this encoder has a button here
-  #define encBtn 4
-
-  encoderIn<encA,encB> encoder;//simple quad encoder driver
-  #define ENC_SENSIVITY 4
-  encoderInStream<encA,encB> encStream(encoder,ENC_SENSIVITY);// simple quad encoder fake Stream
-
-  //a keyboard with only one key as the encoder button
-  keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-  keyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-  serialIn serial(Serial);
-
-  //input from the encoder + encoder button + serial
-  menuIn* inputsList[]={&encStream,&encButton,&serial};
-  chainStream<3> in(inputsList);//3 is the number of inputs
-
-  #define LEDPIN A3
-
-  result doAlert(eventMask e, prompt &item);
-
-  result showEvent(eventMask e,navNode& nav,prompt& item) {
-    Serial.print("event: ");
-    Serial.println(e);
-    return proceed;
-  }
-
-  int test=55;
-
-  result action1(eventMask e,navNode& nav, prompt &item) {
-    Serial.print("action1 event: ");
-    Serial.print(e);
-    Serial.println(", proceed menu");
-    Serial.flush();
-    return proceed;
-  }
-
-  result action2(eventMask e,navNode& nav, prompt &item) {
-    Serial.print("action2 event: ");
-    Serial.print(e);
-    Serial.println(", quiting menu.");
-    Serial.flush();
-    return quit;
-  }
-
-  int ledCtrl=LOW;
-
-  result myLedOn() {
-    ledCtrl=HIGH;
-    return proceed;
-  }
-  result myLedOff() {
-    ledCtrl=LOW;
-    return proceed;
-  }
-
-  TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-    ,VALUE("On",HIGH,doNothing,noEvent)
-    ,VALUE("Off",LOW,doNothing,noEvent)
-  );
-
-  int selTest=0;
-  SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-    ,VALUE("Zero",0,doNothing,noEvent)
-    ,VALUE("One",1,doNothing,noEvent)
-    ,VALUE("Two",2,doNothing,noEvent)
-  );
-
-  int chooseTest=-1;
-  CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-    ,VALUE("First",1,doNothing,noEvent)
-    ,VALUE("Second",2,doNothing,noEvent)
-    ,VALUE("Third",3,doNothing,noEvent)
-    ,VALUE("Last",-1,doNothing,noEvent)
-  );
-
-  //customizing a prompt look!
-  //by extending the prompt class
-  class altPrompt:public prompt {
-  public:
-    altPrompt(constMEM promptShadow& p):prompt(p) {}
-    Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-      return out.printRaw(F("special prompt!"),len);;
-    }
-  };
-
-  MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-    ,OP("Sub1",showEvent,anyEvent)
-    ,OP("Sub2",showEvent,anyEvent)
-    ,OP("Sub3",showEvent,anyEvent)
-    ,altOP(altPrompt,"",showEvent,anyEvent)
-    ,EXIT("<Back")
-  );
-
-  /*extern menu mainMenu;
-  TOGGLE((mainMenu[1].enabled),togOp,"Op 2:",doNothing,noEvent,noStyle
-    ,VALUE("Enabled",enabledStatus,doNothing,noEvent)
-    ,VALUE("disabled",disabledStatus,doNothing,noEvent)
-  );*/
-
-  char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-  char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-  char buf1[]="0x11";
-
-  MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-    ,OP("Op1",action1,anyEvent)
-    ,OP("Op2",action2,enterEvent)
-    //,SUBMENU(togOp)
-    ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-    ,SUBMENU(subMenu)
-    ,SUBMENU(setLed)
-    ,OP("LED On",myLedOn,enterEvent)
-    ,OP("LED Off",myLedOff,enterEvent)
-    ,SUBMENU(selMenu)
-    ,SUBMENU(chooseMenu)
-    ,OP("Alert test",doAlert,enterEvent)
-    ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-    ,EXIT("<Back")
-  );
-
-  #define MAX_DEPTH 2
-
-  /*const panel panels[] MEMMODE={{0,0,16,2}};
-  navNode* nodes[sizeof(panels)/sizeof(panel)];
-  panelsList pList(panels,nodes,1);
-  idx_t tops[MAX_DEPTH];
-  lcdOut outLCD(&lcd,tops,pList);//output device for LCD
-  menuOut* constMEM outputs[] MEMMODE={&outLCD};//list of output devices
-  outputsList out(outputs,1);//outputs list with 2 outputs
-  */
-
-  MENU_OUTPUTS(out,MAX_DEPTH
-    ,LCD_OUT(lcd,{0,0,16,2})
-    ,NONE
-  );
-  NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);//the navigation root object
-
-  result alert(menuOut& o,idleEvent e) {
-    if (e==idling) {
-      o.setCursor(0,0);
-      o.print("alert test");
-      o.setCursor(0,1);
-      o.print("[select] to continue...");
-    }
-    return proceed;
-  }
-
-  result doAlert(eventMask e, prompt &item) {
-    nav.idleOn(alert);
-    return proceed;
-  }
-
-  result idle(menuOut& o,idleEvent e) {
-    switch(e) {
-      case idleStart:o.print("suspending menu!");break;
-      case idling:o.print("suspended...");break;
-      case idleEnd:o.print("resuming menu.");break;
-    }
-    return proceed;
-  }
-
-  void setup() {
-    pinMode(encBtn,INPUT_PULLUP);
-    pinMode(LEDPIN,OUTPUT);
-    Serial.begin(115200);
-    while(!Serial);
-    Serial.println("Arduino Menu Library");Serial.flush();
-    encoder.begin();
-    lcd.begin(16,2);
-    nav.idleTask=idle;//point a function to be used when menu is suspended
-    mainMenu[1].enabled=disabledStatus;
-    nav.showTitle=false;
-    lcd.setCursor(0, 0);
-    lcd.print("Menu 4.x LCD");
-    lcd.setCursor(0, 1);
-    lcd.print("r-site.net");
-    delay(2000);
-  }
-
-  void loop() {
-    nav.poll();
-    digitalWrite(LEDPIN, ledCtrl);
-    delay(100);//simulate a delay as if other tasks are running
-  }
-
-#endif
diff --git a/examples/LCDs/PCF8574/PCF8574/PCF8574.ino b/examples/LCDs/PCF8574/PCF8574/PCF8574.ino
deleted file mode 100644
index 007bc2e3..00000000
--- a/examples/LCDs/PCF8574/PCF8574/PCF8574.ino
+++ /dev/null
@@ -1,214 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Arduino generic menu system
-
-Sep.2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-LCD library:
-Matthias Hertel driver https://github.com/mathertel/LiquidCrystal_PCF8574
-
-Output: I2C LCD
-Inpout: encoder + serial
-*/
-#include <Wire.h>
-#include <LiquidCrystal_PCF8574.h>
-#include <menu.h>//menu macros and objects
-#include <menuIO/PCF8574Out.h>//arduino I2C LCD
-#include <menuIO/encoderIn.h>//quadrature encoder driver and fake stream
-#include <menuIO/keyIn.h>//keyboard driver and fake stream (for the encoder button)
-#include <menuIO/chainStream.h>// concatenate multiple input streams (this allows adding a button to the encoder)
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-//using Matthias Hertel driver https://github.com/mathertel/LiquidCrystal_PCF8574
-LiquidCrystal_PCF8574 lcd(0x27);  // set the LCD address to 0x27 for a 16 chars and 2 line display
-
-// Encoder /////////////////////////////////////
-#define encA 2
-#define encB 3
-//this encoder has a button here
-#define encBtn 4
-
-encoderIn<encA,encB> encoder;//simple quad encoder driver
-#define ENC_SENSIVITY 4
-encoderInStream<encA,encB> encStream(encoder,ENC_SENSIVITY);// simple quad encoder fake Stream
-
-//a keyboard with only one key as the encoder button
-keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-keyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-//input from the encoder + encoder button + serial
-serialIn serial(Serial);
-menuIn* inputsList[]={&encStream,&encButton,&serial};
-chainStream<3> in(inputsList);//3 is the number of inputs
-
-#define LEDPIN A3
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action1 event: ");
-  Serial.print(e);
-  Serial.println(", proceed menu");
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action2 event: ");
-  Serial.print(e);
-  Serial.println(", quiting menu.");
-  Serial.flush();
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-/*extern menu mainMenu;
-TOGGLE((mainMenu[1].enabled),togOp,"Op 2:",doNothing,noEvent,noStyle
-  ,VALUE("Enabled",enabledStatus,doNothing,noEvent)
-  ,VALUE("disabled",disabledStatus,doNothing,noEvent)
-);*/
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  //,SUBMENU(togOp)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-// idx_t tops[MAX_DEPTH]={0,0};
-// const panel panels[] MEMMODE={{0,0,16,2}};
-// navNode* nodes[MAX_DEPTH];
-// panelsList pList(panels,nodes,1);
-// lcdOut outLCD(&lcd,tops,pList);//output device for LCD
-// menuOut* constMEM outputs[] MEMMODE={&outLCD};//list of output devices
-// outputsList out(outputs,1);//outputs list with 1 outputs
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,LCD_OUT(lcd,{0,0,16,2})
-  ,NONE
-);
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);//the navigation root object
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("[select] to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-result idle(menuOut& o,idleEvent e) {
-  switch(e) {
-    case idleStart:o.print("suspending menu!");break;
-    case idling:o.print("suspended...");break;
-    case idleEnd:o.print("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(encBtn,INPUT_PULLUP);
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Arduino Menu Library");Serial.flush();
-  encoder.begin();
-  lcd.begin(16,2);
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  mainMenu[1].enabled=disabledStatus;
-  nav.showTitle=false;
-  lcd.setBacklight(255);
-  lcd.setCursor(0, 0);
-  lcd.print("Menu 4.x LCD");
-  lcd.setCursor(0, 1);
-  lcd.print("r-site.net");
-  delay(2000);
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, ledCtrl);
-  test=(millis()/1000)%101;
-  delay(100);//simulate a delay as if other tasks are running
-}
diff --git a/examples/LCDs/PCF8574/include/readme.txt b/examples/LCDs/PCF8574/include/readme.txt
deleted file mode 100644
index 194dcd43..00000000
--- a/examples/LCDs/PCF8574/include/readme.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-
-This directory is intended for project header files.
-
-A header file is a file containing C declarations and macro definitions
-to be shared between several project source files. You request the use of a
-header file in your project source file (C, C++, etc) located in `src` folder
-by including it, with the C preprocessing directive `#include'.
-
-```src/main.c
-
-#include "header.h"
-
-int main (void)
-{
- ...
-}
-```
-
-Including a header file produces the same results as copying the header file
-into each source file that needs it. Such copying would be time-consuming
-and error-prone. With a header file, the related declarations appear
-in only one place. If they need to be changed, they can be changed in one
-place, and programs that include the header file will automatically use the
-new version when next recompiled. The header file eliminates the labor of
-finding and changing all the copies as well as the risk that a failure to
-find one copy will result in inconsistencies within a program.
-
-In C, the usual convention is to give header files names that end with `.h'.
-It is most portable to use only letters, digits, dashes, and underscores in
-header file names, and at most one dot.
-
-Read more about using header files in official GCC documentation:
-
-* Include Syntax
-* Include Operation
-* Once-Only Headers
-* Computed Includes
-
-https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
diff --git a/examples/OzOledAscii/OzOledAscii.ino b/examples/OzOledAscii/OzOledAscii.ino
deleted file mode 100644
index 13e47efb..00000000
--- a/examples/OzOledAscii/OzOledAscii.ino
+++ /dev/null
@@ -1,166 +0,0 @@
-
-//using https://github.com/kdkanishka/ozoled-oled-display-096-i2c-driver-library
-
-#include <Arduino.h>
-#include "OzOLED.h"
-
-#include <menu.h>
-#include <menuIO/OzOledAsciiOut.h>
-#include <menuIO/serialIn.h>
-using namespace Menu;
-
-//Redefine already existing object
-#define oled OzOled
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e) {
-  Serial.print(e);
-  Serial.println(" action1 executed, proceed menu");Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e,navNode& nav, prompt &item) {
-  Serial.print(e);
-  Serial.println(" action2 executed, quiting menu");
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result ledOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result ledOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",ledOn,enterEvent)
-  ,OP("LED Off",ledOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EXIT("<Back")
-);
-
-
-
-#define MAX_DEPTH 2
-//Only one build-in font 
-#define fontW 8
-#define fontH 8
-
-//describing a menu output device without macros
-//define at least one panel for menu output
-const panel panels[] MEMMODE={{0,0,128/fontW,64/fontH}};
-navNode* nodes[sizeof(panels)/sizeof(panel)];//navNodes to store navigation status
-panelsList pList(panels,nodes,1);//a list of panels and nodes
-idx_t tops[MAX_DEPTH]={0,0};//store cursor positions for each level
-OzOledAsciiOut outOLED(&oled,tops,pList);//oled output device menu driver
-menuOut* constMEM outputs[] MEMMODE={&outOLED};//list of output devices
-outputsList out(outputs,1);//outputs list
-
-//macro to create navigation control root object (nav) using mainMenu
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("press [select]");
-    o.setCursor(0,2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut &o, idleEvent e) {
-  o.clear();
-  switch(e) {
-    case idleStart:o.println("suspending menu!");break;
-    case idling:o.println("suspended...");break;
-    case idleEnd:o.println("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");Serial.flush();
-  oled.init();
-  oled.clearDisplay();
-  //Vertical flip, comment out if display upside down.
-  oled.sendCommand(0xC8);
-  oled.sendCommand(0xA1);
-  //End Vertical flip
-  oled.printString("Hello world!");
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-}
-
-void loop() {
-  nav.poll();
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/SDCard/SDCard/SDCard.ino b/examples/SDCard/SDCard/SDCard.ino
deleted file mode 100644
index 26826f83..00000000
--- a/examples/SDCard/SDCard/SDCard.ino
+++ /dev/null
@@ -1,83 +0,0 @@
-#include <SPI.h>
-#include <SD.h>
-#include <menu.h>
-#include <menuIO/serialIO.h>
-#include <plugin/SDMenu.h>
-
-using namespace Menu;
-
-//from: https://www.arduino.cc/en/Tutorial/listfiles
-// The circuit:
-// * SD card attached to SPI bus as follows:
-// ** MOSI - pin 11
-// ** MISO - pin 12
-// ** CLK - pin 13
-// ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
-//this is for my due tft+sd shield
-#define SDCARD_SS 53
-
-//function to handle file select
-// declared here and implemented bellow because we need
-// to give it as event handler for `filePickMenu`
-// and we also need to refer to `filePickMenu` inside the function
-result filePick(eventMask event, navNode& nav, prompt &item);
-
-
-// SDMenu filePickMenu("SD Card","/",filePick,enterEvent);
-//caching 32 file entries
-CachedSDMenu<32> filePickMenu("SD Card","/",filePick,enterEvent);
-
-//implementing the handler here after filePick is defined...
-result filePick(eventMask event, navNode& nav, prompt &item) {
-  // switch(event) {//for now events are filtered only for enter, so we dont need this checking
-  //   case enterCmd:
-      if (nav.root->navFocus==(navTarget*)&filePickMenu) {
-        Serial.println();
-        Serial.print("selected file:");
-        Serial.println(filePickMenu.selectedFile);
-        Serial.print("from folder:");
-        Serial.println(filePickMenu.selectedFolder);
-      }
-  //     break;
-  // }
-  return proceed;
-}
-
-#define MAX_DEPTH 2
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,SUBMENU(filePickMenu)
-  ,OP("Something else...",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-void setup() {
-  Serial.begin(115200);
-  while (!Serial);
-  Serial.print("Initializing SD card...");
-  if (!SD.begin(SDCARD_SS)) {
-    Serial.println("initialization failed!");
-    while (1);
-  }
-  filePickMenu.begin();//need this after sd begin
-  Serial.println("initialization done.");
-  nav.useAccel=false;
-}
-
-constexpr int menuFPS=25;
-unsigned long nextPool=0;
-void loop() {
-  unsigned long now=millis();
-  if(now>=nextPool) {
-    nav.poll();
-    nextPool=now+1000/menuFPS;
-  }
-}
diff --git a/examples/SSD1306Ascii/.gitignore b/examples/SSD1306Ascii/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/SSD1306Ascii/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/SSD1306Ascii/.travis.yml b/examples/SSD1306Ascii/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/SSD1306Ascii/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/SSD1306Ascii/Button_Navigation/Button_Navigation.ino b/examples/SSD1306Ascii/Button_Navigation/Button_Navigation.ino
deleted file mode 100644
index 99bbc3eb..00000000
--- a/examples/SSD1306Ascii/Button_Navigation/Button_Navigation.ino
+++ /dev/null
@@ -1,229 +0,0 @@
-/**************************************************************************
-  Sketch: MENU NAVIGATION WITH JUST 4 BUTTONS
-
-  This Sketch displays Menu without any Serial Communication and the
-  navigation is performed by 4 buttons attached to D3, D8, D4 and D1.
-  Also, attach led on D11 to control brightness from menu.
-  Default brightness is 15% (check line 78)
-
-   NOTE: By default, navigation buttons use INTERNAL_PULLUP feature.
-         This can be changed by commenting the line 45 in "config.h" file
-
-   Uses SSD1306Ascii Library(https://github.com/greiman/SSD1306Ascii)
-   by Bill Grieman
-
-   Created by Tamojit Saha
-    Github: https://github.com/TamojitSaha
-    Website: https://www.tamojitsaha.info/
-***************************************************************************/
-#include <Arduino.h>
-
-// #include <Wire.h>
-#include "SSD1306Ascii.h"
-#include "SSD1306AsciiWire.h"
-
-#include <menu.h>
-#include <menuIO/SSD1306AsciiOut.h>
-#include <menuIO/keyIn.h>
-//#include <menuIO/chainStream.h>
-using namespace Menu;
-
-SSD1306AsciiWire oled;
-
-#include "config.h"
-
-int ledCtrl = HIGH;  //Default LED State of LED at D11 is LOW
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e, navNode& nav, prompt& item) {
-
-  return proceed;
-}
-
-
-
-result action1(eventMask e) {
-
-  return proceed;
-}
-
-result action2(eventMask e, navNode& nav, prompt &item) {
-  //Serial.print(e);
-  //Serial.println(" action2 executed, quiting menu");
-  return quit;
-}
-
-
-result ledOn() {
-  ledCtrl = HIGH;
-  analogWrite(LED_PIN, 255);
-  return proceed;
-}
-result ledOff() {
-  ledCtrl = LOW;
-  analogWrite(LED_PIN, 0);
-  return proceed;
-}
-
-
-result internalLedOn() {
-  digitalWrite(LED_BUILTIN, HIGH);
-  return proceed;
-}
-result internalLedOff() {
-  analogWrite(LED_BUILTIN, LOW);
-  return proceed;
-}
-
-int brightnessValue = 15;   //Default LED brightness value
-result adjustBrightness() {
-  if (ledCtrl == HIGH) {
-    int pwm = int(2.55 * float(brightnessValue));
-    analogWrite(LED_PIN, pwm);
-  }
-}
-
-
-TOGGLE(ledCtrl, setLed, "Led: ", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
-       , VALUE("On", HIGH, ledOn, enterEvent)//ledOn function is called
-       , VALUE("Off", LOW, ledOff, enterEvent)//ledOff function is called
-      );
-
-int selTest = 0;
-SELECT(selTest, selMenu, "Select", doNothing, noEvent, noStyle
-       , VALUE("Zero", 0, doNothing, noEvent)
-       , VALUE("One", 1, doNothing, noEvent)
-       , VALUE("Two", 2, doNothing, noEvent)
-      );
-
-int chooseTest = -1;
-CHOOSE(chooseTest, chooseMenu, "Choose", doNothing, noEvent, noStyle
-       , VALUE("First", 1, doNothing, noEvent)
-       , VALUE("Second", 2, doNothing, noEvent)
-       , VALUE("Third", 3, doNothing, noEvent)
-       , VALUE("Last", -1, doNothing, noEvent)
-      );
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt: public prompt {
-  public:
-    altPrompt(constMEM promptShadow& p): prompt(p) {}
-    Used printTo(navRoot &root, bool sel, menuOut& out, idx_t idx, idx_t len, idx_t) override {
-      return out.printRaw(F("special prompt!"), len);
-    }
-};
-
-MENU(subMenu, "Sub-Menu", showEvent, anyEvent, noStyle
-     , OP("Sub1", showEvent, anyEvent)
-     , OP("Sub2", showEvent, anyEvent)
-     , OP("Sub3", showEvent, anyEvent)
-     , altOP(altPrompt, "", showEvent, anyEvent)
-     , EXIT("<Back")
-    );
-
-MENU(mainMenu, "Main menu", doNothing, noEvent, wrapStyle
-     , OP("Op1", action1, anyEvent)
-     , OP("Op2", action2, enterEvent)
-     /* FIELD Parameters :
-
-        Action Name(function name), Action Heading, Action Heading Unit,
-        range_lowest, range_highest, range_increment_step,
-        range_decrement_step
-     */
-     , FIELD(brightnessValue, "Brightness", "%", 0, 100, 5, 5, adjustBrightness, enterEvent, wrapStyle)
-     , SUBMENU(subMenu)
-     , SUBMENU(setLed)
-     , OP("LED On", internalLedOn, enterEvent) // will turn on built-in LED
-     , OP("LED Off", internalLedOff, enterEvent)// will turn off built-in LED
-     , SUBMENU(selMenu)
-     , SUBMENU(chooseMenu)
-     , OP("Alert test", doAlert, enterEvent)
-     , EXIT("<Back")
-    );
-
-
-
-//describing a menu output device without macros
-//define at least one panel for menu output
-const panel panels[] MEMMODE = {{0, 0, 128 / fontW, 64 / fontH}};
-navNode* nodes[sizeof(panels) / sizeof(panel)]; //navNodes to store navigation status
-panelsList pList(panels, nodes, 1); //a list of panels and nodes
-idx_t tops[MAX_DEPTH] = {0, 0}; //store cursor positions for each level
-
-#ifdef LARGE_FONT
-SSD1306AsciiOut outOLED(&oled, tops, pList, 8, 2); //oled output device menu driver
-
-#else
-SSD1306AsciiOut outOLED(&oled, tops, pList, 5, 1); //oled output device menu driver
-#endif
-
-menuOut* constMEM outputs[]  MEMMODE  = {&outOLED}; //list of output devices
-outputsList out(outputs, 1); //outputs list
-
-#ifdef NAV_BUTTONS_INPUT_PULLUP
-//build a map of keys to menu commands
-keyMap joystickBtn_map[] = {
-  { -BTN_SEL, defaultNavCodes[enterCmd].ch} ,
-  { -BTN_UP, defaultNavCodes[upCmd].ch} ,
-  { -BTN_DOWN, defaultNavCodes[downCmd].ch}  ,
-  { -BTN_ESC, defaultNavCodes[escCmd].ch}  ,
-};
-keyIn<TOTAL_NAV_BUTTONS> joystickBtns(joystickBtn_map);//the input driver
-#else
-//build a map of keys to menu commands
-keyMap joystickBtn_map[] = {
-  { BTN_SEL, defaultNavCodes[enterCmd].ch} ,
-  { BTN_UP, defaultNavCodes[upCmd].ch} ,
-  { BTN_DOWN, defaultNavCodes[downCmd].ch}  ,
-  { BTN_ESC, defaultNavCodes[escCmd].ch},
-};
-keyIn<TOTAL_NAV_BUTTONS> joystickBtns(joystickBtn_map);//the input driver
-#endif
-
-NAVROOT(nav, mainMenu, MAX_DEPTH, joystickBtns, out);
-
-result alert(menuOut& o, idleEvent e) {
-  if (e == idling) {
-    o.setCursor(0, 0);
-    o.print("alert test");
-    o.setCursor(0, 1);
-    o.print("press [select]");
-    o.setCursor(0, 2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut &o, idleEvent e) {
-  o.clear();
-  switch (e) {
-    case idleStart: o.println("suspending menu!"); break;
-    case idling: o.println("suspended..."); break;
-    case idleEnd: o.println("resuming menu."); break;
-  }
-  return proceed;
-}
-
-void setup() {
-  joystickBtns.begin();
-  pinMode(LED_PIN, OUTPUT);
-  pinMode(LED_BUILTIN, OUTPUT);
-  Wire.begin();
-  oled.begin(&Adafruit128x64, OLED_I2C_ADDRESS); //check config
-  oled.setFont(menuFont);
-  oled.clear();
-  nav.idleTask = idle; //point a function to be used when menu is suspended
-}
-
-void loop() {
-  nav.poll();
-  delay(1);//simulate a delay when other tasks are done
-}
diff --git a/examples/SSD1306Ascii/Button_Navigation/config.h b/examples/SSD1306Ascii/Button_Navigation/config.h
deleted file mode 100644
index 7a414c41..00000000
--- a/examples/SSD1306Ascii/Button_Navigation/config.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*config.h*/
-
-/* List of Supported Fonts
- *
-  Arial14,
-  Arial_bold_14,
-  Callibri11,
-  Callibri11_bold,
-  Callibri11_italic,
-  Callibri15,
-  Corsiva_12,
-  fixed_bold10x15,
-  font5x7,    //Do not use in LARGE_FONT, can use as default font
-  font8x8,
-  Iain5x7,    //Do not use in LARGE_FONT, can use as default font
-  lcd5x7,     //Do not use in LARGE_FONT, can use as default font
-  Stang5x7,   //Do not use in LARGE_FONT, can use as default font
-  System5x7,  //Do not use in LARGE_FONT, can use as default font
-  TimesNewRoman16,
-  TimesNewRoman16_bold,
-  TimesNewRoman16_italic,
-  utf8font10x16,
-  Verdana12,
-  Verdana12_bold,
-  Verdana12_italic,
-  X11fixed7x14,
-  X11fixed7x14B,
-  ZevvPeep8x16
- *  
- */
-
-#define OLED_I2C_ADDRESS 0x3C     //Defined OLED I2C Address
-
-/*
- * Define your font from the list. 
- * Default font: lcd5x7
- * Comment out the following for using the default font.
- */
-#define LARGE_FONT Verdana12
-
-//Navigate buttons
-#define BTN_SEL     3                 // Select button
-#define BTN_UP      8                 // Up Button
-#define BTN_DOWN    4                 // Down Button
-#define BTN_ESC     1                 // Exit Button
-// Comment the following to disable internal pullup for Navigate buttons
-#define NAV_BUTTONS_INPUT_PULLUP
-
-#define TOTAL_NAV_BUTTONS 4       // Total Navigation Button used
-
-/*Demonstrate PWM with LED on D11*/
-#define LED_PIN 11                //Defined LED Pin to D11
-
-#define MAX_DEPTH 2
-
-#ifdef LOC
-// #define LARGE_FONT
-#define INV
-#endif
- 
- /*Do not change the values(recomended)*/
-#ifdef LARGE_FONT
-#define menuFont LARGE_FONT
-#define fontW 8
-#define fontH 16
-#else
-// #define menuFont System5x7
-#define menuFont lcd5x7
-#define fontW 5
-#define fontH 8
-#endif
diff --git a/examples/SSD1306Ascii/SSD1306Ascii/SSD1306Ascii.ino b/examples/SSD1306Ascii/SSD1306Ascii/SSD1306Ascii.ino
deleted file mode 100644
index 33f855d4..00000000
--- a/examples/SSD1306Ascii/SSD1306Ascii/SSD1306Ascii.ino
+++ /dev/null
@@ -1,227 +0,0 @@
-/* List of Supported Fonts
-
-  Arial14,
-  Arial_bold_14,
-  Callibri11,
-  Callibri11_bold,
-  Callibri11_italic,
-  Callibri15,
-  Corsiva_12,
-  fixed_bold10x15,
-  font5x7,
-  font8x8,
-  Iain5x7,
-  lcd5x7,
-  Stang5x7,
-  System5x7,
-  TimesNewRoman16,
-  TimesNewRoman16_bold,
-  TimesNewRoman16_italic,
-  utf8font10x16,
-  Verdana12,
-  Verdana12_bold,
-  Verdana12_italic,
-  X11fixed7x14,
-  X11fixed7x14B,
-  ZevvPeep8x16
-
-*/
-
-//Library Dependency : SSD1306Ascii by Bill Greiman
-//Link : https://github.com/greiman/SSD1306Ascii
-// Modified sketch by Tamojit Saha(https://github.com/TamojitSaha)
-
-
-#include <Arduino.h>
-
-constexpr int OLED_SDA=4;
-constexpr int OLED_SDC=5;
-
-#define I2C_ADDRESS 0x3C
-// #include <Wire.h>
-#include "SSD1306Ascii.h"
-#include "SSD1306AsciiWire.h"
-
-#include <menu.h>
-#include <menuIO/SSD1306AsciiOut.h>
-#include <menuIO/serialIO.h>
-//enable this include if using esp8266
-// #include <menuIO/esp8266Out.h>
-using namespace Menu;
-
-//Define your font here. Default font: lcd5x7
-#define menuFont X11fixed7x14
-#define fontW 7
-#define fontH 15
-
-// #define menuFont System5x7
-// #define menuFont lcd5x7
-// #define fontW 5
-// #define fontH 8
-
-SSD1306AsciiWire oled;
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e, navNode& nav, prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test = 55;
-
-result action1(eventMask e) {
-  Serial.print(e);
-  Serial.println(" action1 executed, proceed menu"); Serial.flush();
-  trace(if (e == enterEvent) oled.clear(0, oled.displayWidth(), 2, 3));
-  return proceed;
-}
-
-result action2(eventMask e, navNode& nav, prompt &item) {
-  Serial.print(e);
-  Serial.println(" action2 executed, quiting menu");
-  return quit;
-}
-
-int ledCtrl = LOW;
-
-result myLedOn() {
-  ledCtrl = HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl = LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl, setLed, "Led: ", doNothing, noEvent, noStyle //,doExit,enterEvent,noStyle
-       , VALUE("On", HIGH, doNothing, noEvent)
-       , VALUE("Off", LOW, doNothing, noEvent)
-      );
-
-int selTest = 0;
-SELECT(selTest, selMenu, "Select", doNothing, noEvent, noStyle
-       , VALUE("Zero", 0, doNothing, noEvent)
-       , VALUE("One", 1, doNothing, noEvent)
-       , VALUE("Two", 2, doNothing, noEvent)
-      );
-
-int chooseTest = -1;
-CHOOSE(chooseTest, chooseMenu, "Choose", doNothing, noEvent, noStyle
-       , VALUE("First", 1, doNothing, noEvent)
-       , VALUE("Second", 2, doNothing, noEvent)
-       , VALUE("Third", 3, doNothing, noEvent)
-       , VALUE("Last", -1, doNothing, noEvent)
-      );
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt: public prompt {
-  public:
-    altPrompt(constMEM promptShadow& p): prompt(p) {}
-    Used printTo(navRoot &root, bool sel, menuOut& out, idx_t idx, idx_t len, idx_t) override {
-      return out.printRaw(F( "special prompt!"), len);
-    }
-};
-
-MENU(subMenu, "Sub-Menu", showEvent, anyEvent, noStyle
-     , OP("Sub1", showEvent, anyEvent)
-     , OP("Sub2", showEvent, anyEvent)
-     , OP("Sub3", showEvent, anyEvent)
-     , altOP(altPrompt, "", showEvent, anyEvent)
-     , EXIT("<Back")
-    );
-
-MENU(mainMenu, "Main menu", doNothing, noEvent, wrapStyle
-     , OP("Op1", action1, anyEvent)
-     , OP("Op2", action2, enterEvent)
-     , FIELD(test, "Test", "%", 0, 100, 10, 1, doNothing, noEvent, wrapStyle)
-     , SUBMENU(subMenu)
-     , SUBMENU(setLed)
-     , OP("LED On", myLedOn, enterEvent)
-     , OP("LED Off", myLedOff, enterEvent)
-     , SUBMENU(selMenu)
-     , SUBMENU(chooseMenu)
-     , OP("Alert test", doAlert, enterEvent)
-     , EXIT("<Back")
-    );
-
-#define MAX_DEPTH 2
-
-//define output device
-idx_t serialTops[MAX_DEPTH] = {0};
-serialOut outSerial(Serial, serialTops);
-
-//describing a menu output device without macros
-//define at least one panel for menu output
-constMEM panel panels[] MEMMODE = {{0, 0, 128 / fontW, 64 / fontH}};
-navNode* nodes[sizeof(panels) / sizeof(panel)]; //navNodes to store navigation status
-panelsList pList(panels, nodes, 1); //a list of panels and nodes
-idx_t tops[MAX_DEPTH] = {0, 0}; //store cursor positions for each level
-SSD1306AsciiOut outOLED(&oled, tops, pList, 8, 1+((fontH-1)>>3) ); //oled output device menu driver
-menuOut* constMEM outputs[] MEMMODE = {&outOLED, &outSerial}; //list of output devices
-outputsList out(outputs, sizeof(outputs) / sizeof(menuOut*)); //outputs list
-
-//macro to create navigation control root object (nav) using mainMenu
-serialIn serial(Serial);
-NAVROOT(nav, mainMenu, MAX_DEPTH, serial, out);
-
-result alert(menuOut& o, idleEvent e) {
-  if (e == idling) {
-    o.setCursor(0, 0);
-    o.print("alert test");
-    o.setCursor(0, 1);
-    o.print("press [select]");
-    o.setCursor(0, 2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut &o, idleEvent e) {
-  o.clear();
-  if (&o==&outOLED) {
-    if (e==idling) {
-      o.println("OLED");
-      o.println("Suspended menu");
-    }
-  } else
-    switch (e) {
-      case idleStart: o.println("suspending menu!"); break;
-      case idling: o.println("suspended..."); break;
-      case idleEnd: o.println("resuming menu."); break;
-    }
-  return proceed;
-}
-
-void setup() {
-  Serial.begin(115200);
-  while (!Serial);
-  Serial.println("menu 4.x test"); Serial.flush();
-  pinMode(A0, INPUT);
-  Wire.begin();
-  oled.begin(&Adafruit128x64, I2C_ADDRESS);
-  oled.setFont(menuFont);
-
-  oled.clear();
-  oled.setCursor(0, 0);
-  oled.print("menu 4.x test");
-  oled.setCursor(0, 2);
-  oled.print("SSD1306Ascii");
-  delay(2000);
-  oled.clear();
-  nav.idleTask = idle; //point a function to be used when menu is suspended
-}
-
-void loop() {
-  //if (!digitalRead(A0)) action1(enterEvent);
-  nav.poll();
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/SSD1306Ascii/platformio.ini b/examples/SSD1306Ascii/platformio.ini
deleted file mode 100644
index a3b6b3a7..00000000
--- a/examples/SSD1306Ascii/platformio.ini
+++ /dev/null
@@ -1,43 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-; src_dir=Button_Navigation
-src_dir=SSD1306Ascii
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-upload_speed=57600
-build_flags = -DMENU_DEBUG
-src_build_flags = !echo "-Wno-write-strings -Wno-reorder -fno-strict-aliasing -DLOC="$PLATFORMIO_LOC
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-;; build_flags = -lstdc++
-
-; [env:esp12e]
-; platform = espressif8266
-; board = esp12e
-; framework = arduino
-; upload_speed=921600
-; build_flags = -lstdc++ -DDEBUG
-
-; [env:wemos]
-; platform = espressif8266
-; board = d1_mini_pro
-; framework = arduino
-; ; upload_speed=1500000
-; upload_speed=921600
diff --git a/examples/SdFat/SdFat/SdFat.ino b/examples/SdFat/SdFat/SdFat.ino
deleted file mode 100644
index 27e3c832..00000000
--- a/examples/SdFat/SdFat/SdFat.ino
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <SPI.h>
-#include <SdFat.h>
-#include <menu.h>
-#include <menuIO/serialIO.h>
-#include <plugin/SdFatMenu.h>
-//enable this include if using esp8266
-#include <menuIO/esp8266Out.h>
-
-using namespace Menu;
-
-//esp8266 SS (wemos mini)
-#define SDCARD_SS SS
-SdFat sd;
-
-//function to handle file select
-// declared here and implemented bellow because we need
-// to give it as event handler for `filePickMenu`
-// and we also need to refer to `filePickMenu` inside the function
-result filePick(eventMask event, navNode& nav, prompt &item);
-
-
-SDMenuT<CachedFSO<SdFat,32>> filePickMenu(sd,"SD Card","/",filePick,enterEvent);
-
-//implementing the handler here after filePick is defined...
-result filePick(eventMask event, navNode& nav, prompt &item) {
-  // switch(event) {//for now events are filtered only for enter, so we dont need this checking
-  //   case enterCmd:
-      if (nav.root->navFocus==(navTarget*)&filePickMenu) {
-        Serial.println();
-        Serial.print("selected file:");
-        Serial.println(filePickMenu.selectedFile);
-        Serial.print("from folder:");
-        Serial.println(filePickMenu.selectedFolder);
-      }
-  //     break;
-  // }
-  return proceed;
-}
-
-#define MAX_DEPTH 2
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,SUBMENU(filePickMenu)
-  ,OP("Something else...",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-void setup() {
-  Serial.begin(115200);
-  while (!Serial);
-  Serial.print("Initializing SD card...");
-  if (!sd.begin(SDCARD_SS, SD_SCK_MHZ(50))) {
-    sd.initErrorHalt();
-  }
-  filePickMenu.begin();//need this after sd begin
-  Serial.println("initialization done.");
-  nav.useAccel=false;
-}
-
-constexpr int menuFPS=25;
-unsigned long nextPool=0;
-void loop() {
-  unsigned long now=millis();
-  if(now>=nextPool) {
-    nav.poll();
-    nextPool=now+1000/menuFPS;
-  }
-}
diff --git a/examples/Serial/ansiSerial/.gitignore b/examples/Serial/ansiSerial/.gitignore
deleted file mode 100644
index e05273b2..00000000
--- a/examples/Serial/ansiSerial/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.clang_complete
-.gcc-flags.json
-.piolibdeps
\ No newline at end of file
diff --git a/examples/Serial/ansiSerial/.travis.yml b/examples/Serial/ansiSerial/.travis.yml
deleted file mode 100644
index 72c6e43f..00000000
--- a/examples/Serial/ansiSerial/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/stable/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/stable/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/stable/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/Serial/ansiSerial/ansiSerial/ansiSerial.ino b/examples/Serial/ansiSerial/ansiSerial/ansiSerial.ino
deleted file mode 100644
index 1cda842d..00000000
--- a/examples/Serial/ansiSerial/ansiSerial/ansiSerial.ino
+++ /dev/null
@@ -1,344 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Oct. 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu to ANSI serial terminal
-output: ANSI Serial terminal
-input: Serial
-
-draw color menu on ansi serial device
-to see the result on linux machines use:
-
-screen /dev/ttyUSBn 115200
-
-replace the port (/dev/ttyUSBn) with your appropriate port
-screen utility exits with [Ctrl+A \ y]
-
-www.r-site.net
-***/
-#include <menu.h>
-#include <menuIO/ansiSerialOut.h>
-#include <menuIO/serialIn.h>
-// #include <streamFlow.h>
-#include <AnsiStream.h>
-
-using namespace Menu;
-using namespace ANSI;
-
-#ifdef DEBUG
-Print& operator<<(Print&o, Menu::prompt&p) {
-  print_P(o,p.getText());
-  return o;
-}
-#endif
-
-#define LEDPIN LED_BUILTIN
-
-// define menu colors --------------------------------------------------------
-//each color is in the format:
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-const colorDef<uint8_t> colors[] MEMMODE={
-  {{BLUE,WHITE}  ,{BLUE,WHITE,WHITE}},//bgColor
-  {{BLACK,BLACK} ,{WHITE,BLUE,BLUE}},//fgColor
-  {{BLACK,BLACK} ,{YELLOW,YELLOW,RED}},//valColor
-  {{BLACK,BLACK} ,{WHITE,BLUE,YELLOW}},//unitColor
-  {{BLACK,BLACK} ,{BLACK,BLUE,RED}},//cursorColor
-  {{BLACK,BLACK}  ,{BLUE,RED,BLUE}},//titleColor
-};
-
-//define menu outputs ------------------------------------------------
-#define MAX_DEPTH 4
-// const panel panels[] MEMMODE={{1,1,16,10},{18,1,16,10},{36,1,16,10}};
-// navNode* nodes[sizeof(panels)/sizeof(panel)];
-// panelsList pList(panels,nodes,sizeof(panels)/sizeof(panel));
-// idx_t ansi_tops[MAX_DEPTH];
-// ansiSerialOut ansi(Serial,colors,ansi_tops,pList);//the output device, ansi-terminal Cols x Rows
-// menuOut* constMEM outputs[] MEMMODE={&ansi};
-// outputsList out(outputs,1);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,ANSISERIAL_OUT(Serial,colors,{1,1,26,10},{28,1,16,10},{46,1,16,10})
-  ,NONE//must have 2 items at least
-);
-
-result doAlert(eventMask e, prompt &item);
-
-void putColor(
-  menuOut& out,
-  colorDefs def,
-  bool selected,
-  status stat,
-  bool edit
-  ,int x,int y
-) {
-    out.fill(x,y,x+8,y,' ',bgColor,selected,stat,edit);
-    out.setColor(def,selected,stat,edit);
-    out.setCursor(x,y-1);
-    out<<"XX";
-}
-
-void showColorDef(menuOut& out,colorDefs def,int x,int y) {
-  out<<ANSI::setBackgroundColor(BLACK)<<ANSI::setForegroundColor(WHITE);
-  out<<ANSI::xy(x+1,y+1)<<def<<ANSI::xy(x+16,y+1)<<"Disabled | Enabled | Editing  "<<endl;
-  out<<ANSI::setBackgroundColor(BLACK)<<ANSI::setForegroundColor(WHITE);
-  out<<ANSI::xy(x+1,y+2)<<"normal";
-  putColor(out, def, false, disabledStatus, false,x+15,y+1);
-  putColor(out, def, false, enabledStatus, false,x+25,y+1);
-  out<<ANSI::setBackgroundColor(BLACK)<<ANSI::setForegroundColor(WHITE);
-  out<<ANSI::xy(x+1,y+3)<<"selected";
-  putColor(out, def, true, disabledStatus, false,x+15,y+2);
-  putColor(out, def, true, enabledStatus, false,x+25,y+2);
-  putColor(out, def, true, enabledStatus, true,x+35,y+2);
-}
-
-result showColors(menuOut& o,idleEvent e) {
-  switch(e) {
-    case idling: for(int c=0;c<nColors;c++) showColorDef(o,(colorDefs)c,0,c<<2); break;
-    default:
-      o<<ANSI::xy(80,25)<<ANSI::eraseScreen()<<ANSI::xy(1,1);
-      break;
-  }
-  return proceed;
-}
-
-result showChars(menuOut& o,idleEvent e) {
-  switch(e) {
-    case idling:
-      //o<<"len:"<<strlen(box_top);
-      o<<F("╭─┬╮")<<endl;
-      o<<F("│ ││")<<endl;
-      o<<F("├─┼┤")<<endl;
-      o<<F("╰─┴╯")<<endl;
-      break;
-    default:
-      o<<ANSI::setForegroundColor(WHITE)
-        <<ANSI::setBackgroundColor(BLACK)
-        <<ANSI::xy(80,25)
-        <<ANSI::eraseScreen()
-        <<ANSI::xy(1,1);
-      break;
-  }
-  return proceed;
-}
-
-void showCharsMap(eventMask event, navNode& nav) {nav.root->idleOn(showChars);}
-
-void showOutColors(eventMask event, navNode& nav) {nav.root->idleOn(showColors);}
-
-//menu definition ------------------------------------
-// menu aux functions and vars ------------------------------------------------
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial
-    <<ANSI::xy(0,13)
-    <<ANSI::setForegroundColor(WHITE)
-    <<ANSI::setBackgroundColor(BLACK)
-    <<ANSI::eraseLine()
-    <<e<<" on ";
-  #ifdef DEBUG
-    Serial<<item;
-  #endif
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e,navNode& nav, prompt &item) {
-  Serial
-    <<ANSI::xy(0,13)
-    <<ANSI::setForegroundColor(WHITE)
-    <<ANSI::setBackgroundColor(BLACK)
-    <<e<<" event on ";
-    #ifdef DEBUG
-      Serial<<item;
-    #endif
-    Serial<<", proceed menu";
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e,navNode& nav, prompt &item);
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// menu structure
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);
-  }
-};
-
-MENU(bigMenu,"BigMenu",doNothing,noEvent,noStyle
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-);
-
-MENU(subSubMenu,"Sub-Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("SSub1",doNothing,noEvent)
-  ,OP("SSub2",doNothing,noEvent)
-  ,SUBMENU(bigMenu)
-  ,EXIT("<Back")
-);//just to test depth limit
-
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"custom",showEvent,anyEvent)
-  ,SUBMENU(subSubMenu)
-  ,EXIT("<Back")
-);
-
-uint16_t year=2017;
-uint16_t month=10;
-uint16_t day=7;
-
-//define a pad style menu (single line menu)
-//here with a set of fields to enter a date in YYYY/MM/DD format
-altMENU(menu,birthDate,"Birth",doNothing,noEvent,noStyle,(systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
-  ,FIELD(year,"","/",1900,3000,20,1,doNothing,noEvent,noStyle)
-  ,FIELD(month,"","/",1,12,1,0,doNothing,noEvent,wrapStyle)
-  ,FIELD(day,"","",1,31,1,0,doNothing,noEvent,wrapStyle)
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(birthDate)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Show colors",showOutColors,enterEvent)
-  ,OP("Show characters",showCharsMap,enterEvent)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-////////////////////////////////////////////////////////////////////////
-// menu navigation root object
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-result action2(eventMask e,navNode& nav, prompt &item) {
-  Serial<<ANSI::xy(24,nav.sel+nav.root->showTitle);
-  #ifdef DEBUG
-    Serial<<item;
-  #endif
-  Serial<<" "<<e<<" event on ";
-  #ifdef DEBUG
-    Serial<<item;
-  #endif
-  Serial<<", quiting menu.";
-  Serial.flush();
-  return quit;
-}
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling)
-    o <<ANSI::xy(0,0)
-      <<ANSI::setBackgroundColor(BLACK)
-      <<ANSI::setForegroundColor(WHITE);
-    Serial<<"alert test"
-      <<endl
-      <<"press [select] to continue..."
-      <<endl;
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended -----------------------------------------------
-result idle(menuOut& o,idleEvent e) {
-  switch(e) {
-    //case idleStart:o<<"suspending menu!"<<endl;break;
-    case idling:
-      Serial
-        <<ANSI::xy(0,0)
-        <<ANSI::setBackgroundColor(BLACK)
-        <<ANSI::setForegroundColor(WHITE);
-      Serial<<"suspended..."<<endl;
-      break;
-    default: break;
-    //case idleEnd:o<<"resuming menu."<<endl;break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial<<"menu 4.x test"<<endl;Serial.flush();
-  //nav.idleTask=idle;//point a function to be used when menu is suspended
-  //mainMenu[1].enabled=disabledStatus;
-  //nav.showTitle=true;
-  //nav.printMenu(1);
-  //ansi.fill(1, 1, 2, 2, 'X');
-  //Serial<<"pList[0]:{"<<pList[0].x<<","<<pList[0].y<<","<<pList[0].w<<","<<pList[0].h<<"}"<<endl;
-  delay(1000);
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/Serial/ansiSerial/ansiSerial/boxTable.hpp b/examples/Serial/ansiSerial/ansiSerial/boxTable.hpp
deleted file mode 100644
index 712fcaf8..00000000
--- a/examples/Serial/ansiSerial/ansiSerial/boxTable.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-
-//TRBL 0 1 2 3 4 5 6 7
-//0000 ░ ▒ ▓ █ ▌ ▍ ▎ ▏
-//0001 ▝ ▐ ▙ ▇ ▃
-//0010 ▗ ▄ ▛ ▆ ▂
-//0011 ┐ ╮ ╖ ╕ ╗ ┓ ┒ ┑
-//0100 ▖ ▌ ▜ ▅ ▁
-//0101 ─ ─ ─ ═ ═ ━ ─ ━
-//0110 ┌ ╭ ╓ ╒ ╔ ┏ ┎ ┍
-//0111 ┬ ┬ ╥ ╤ ╦ ┳ ┰ ┯
-//1000 ▘ ▀ ▟ ▅
-//1001 ┘ ╯ ╜ ╛ ╝ ┛ ┚ ┙
-//1010 │ │ ║ │ ║ ┃ ┃ │
-//1011 ┤ ┤ ╢ ╡ ╣ ┫ ┨ ┥
-//1100 └ ╰ ╙ ╘ ╚ ┗ ┖ ┕
-//1101 ┴ ┴ ╨ ╧ ╩ ┻ ┸ ┷
-//1110 ├ ├ ╟ ╞ ╠ ┣ ┠ ┝
-//1111 ┼ ┼ ╫ ╪ ╬ ╋ ╂ ┿
-
-//this cannot be composed (unless using macros :\)
-#define LR01 '─'
-#define TB01 '│'
-#define LT01 '╯'
-#define LB01 '╮'
-#define RT01 '╰'
-#define RB01 '╭'
-#define LRB01 '┬'
-#define LRT01 '┴'
-#define LTB01 '┤'
-#define RTB01 '├'
-#define LRTB01 '┼'
-
-#define LR11 '─'
-#define TB11 '│'
-#define LT11 '┘'
-#define LB11 '┐'
-#define RT11 '└'
-#define RB11 '┌'
-#define LRB11 '┬'
-#define LRT11 '┴'
-#define LTB11 '┤'
-#define RTB11 '├'
-#define LRTB11 '┼'
diff --git a/examples/Serial/ansiSerial/platformio.ini b/examples/Serial/ansiSerial/platformio.ini
deleted file mode 100644
index aabedc0d..00000000
--- a/examples/Serial/ansiSerial/platformio.ini
+++ /dev/null
@@ -1,59 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter, extra scripting
-;   Upload options: custom port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/en/stable/projectconf.html
-
-[platformio]
-src_dir=ansiSerial
-; lib_dir=~/Arduino/Libraries
-
-; [env:redbear_blenano2]
-; platform = nordicnrf52
-; board = redbear_blenano2
-; framework = arduino
-; build_flags =-DNODEBUG -DARDUINO=10805
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -DNODEBUG
-
-; [env:nanoatmega328]
-; platform = atmelavr
-; board = nanoatmega328
-; framework = arduino
-; upload_port=/dev/ttyUSB*
-; upload_flags=-V -cusbasp
-; build_flags = -DNODEBUG
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++
-
-; [env:due]
-; platform = atmelsam
-; board = due
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG -DNOTRACE
-
-;[env:esp01_1m]
-;platform = espressif8266
-;board = esp01_1m
-;framework = arduino
-;build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++
-
-; [env:esp12e]
-; platform = espressif8266
-; board = esp12e
-; framework = arduino
-; upload_speed=921600
-; build_flags = -Wno-comment -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
diff --git a/examples/Serial/serialio/.gitignore b/examples/Serial/serialio/.gitignore
deleted file mode 100644
index e05273b2..00000000
--- a/examples/Serial/serialio/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.clang_complete
-.gcc-flags.json
-.piolibdeps
\ No newline at end of file
diff --git a/examples/Serial/serialio/.travis.yml b/examples/Serial/serialio/.travis.yml
deleted file mode 100644
index 72c6e43f..00000000
--- a/examples/Serial/serialio/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/stable/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/stable/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/stable/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/Serial/serialio/include/readme.txt b/examples/Serial/serialio/include/readme.txt
deleted file mode 100644
index 194dcd43..00000000
--- a/examples/Serial/serialio/include/readme.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-
-This directory is intended for project header files.
-
-A header file is a file containing C declarations and macro definitions
-to be shared between several project source files. You request the use of a
-header file in your project source file (C, C++, etc) located in `src` folder
-by including it, with the C preprocessing directive `#include'.
-
-```src/main.c
-
-#include "header.h"
-
-int main (void)
-{
- ...
-}
-```
-
-Including a header file produces the same results as copying the header file
-into each source file that needs it. Such copying would be time-consuming
-and error-prone. With a header file, the related declarations appear
-in only one place. If they need to be changed, they can be changed in one
-place, and programs that include the header file will automatically use the
-new version when next recompiled. The header file eliminates the labor of
-finding and changing all the copies as well as the risk that a failure to
-find one copy will result in inconsistencies within a program.
-
-In C, the usual convention is to give header files names that end with `.h'.
-It is most portable to use only letters, digits, dashes, and underscores in
-header file names, and at most one dot.
-
-Read more about using header files in official GCC documentation:
-
-* Include Syntax
-* Include Operation
-* Once-Only Headers
-* Computed Includes
-
-https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
diff --git a/examples/Serial/serialio/platformio.ini b/examples/Serial/serialio/platformio.ini
deleted file mode 100644
index b846d8c6..00000000
--- a/examples/Serial/serialio/platformio.ini
+++ /dev/null
@@ -1,80 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter, extra scripting
-;   Upload options: custom port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/en/stable/projectconf.html
-
-[platformio]
-src_dir=serialio
-; lib_dir=~/Arduino/Libraries
-
-; [env:yun]
-; platform = atmelavr
-; board=yun
-; framework = arduino
-; build_flags = -DNODEBUG
-;
-; [env:mzeropro]
-; platform = atmelsam
-; board=mzeropro
-; framework = arduino
-; build_flags = -DNODEBUG
-;
-; [env:mzeroproUSB]
-; platform = atmelsam
-; board=mzeroproUSB
-; framework = arduino
-; build_flags = -DNODEBUG
-;
-; [env:mzeroUSB]
-; platform = atmelsam
-; board=mzeroUSB
-; framework = arduino
-; build_flags = -DNODEBUG
-;
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -DNO_MENU_DEBUG -Wno-strict-aliasing -Wno-sign-compare -Wno-write-strings
-;
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++
-;
-; [env:due]
-; platform = atmelsam
-; board = due
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG -DNOTRACE
-;
-; [env:esp01_1m]
-; platform = espressif8266
-; board = esp01_1m
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++
-;
-; [env:uno]
-; platform = atmelavr
-; board = uno
-; framework = arduino
-; upload_speed=921600
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++ -DDEBUG
-
-; [env:uno]
-; platform = atmelavr
-; board = uno
-; framework = arduino
-;
-; [env:redbear_blenano2]
-; platform = nordicnrf52
-; board = redbear_blenano2
-; framework = arduino
-; build_flags =-DNODEBUG -DARDUINO=10805
diff --git a/examples/Serial/serialio/serialio/serialio.ino b/examples/Serial/serialio/serialio/serialio.ino
deleted file mode 100644
index ca8febe8..00000000
--- a/examples/Serial/serialio/serialio/serialio.ino
+++ /dev/null
@@ -1,186 +0,0 @@
-/********************
-Arduino generic menu system
-
-Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-output: Serial
-input: Serial
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-
-result zZz() {Serial.println("zZz");return proceed;}
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-float test=55;
-
-result action1(eventMask e) {
-  Serial.print(e);
-  Serial.println(" action1 executed, proceed menu");
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e, prompt &item) {
-  Serial.print(e);
-  Serial.print(" action2 executed, quiting menu");
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  // altPrompt(constMEM promptShadow& p):prompt(p) {}
-  using prompt::prompt;
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-uint16_t year=2017;
-uint16_t month=10;
-uint16_t day=7;
-
-//define a pad style menu (single line menu)
-//here with a set of fields to enter a date in YYYY/MM/DD format
-//altMENU(menu,birthDate,"Birth",doNothing,noEvent,noStyle,(systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
-PADMENU(birthDate,"Birth",doNothing,noEvent,noStyle
-  ,FIELD(year,"","/",1900,3000,20,1,doNothing,noEvent,noStyle)
-  ,FIELD(month,"","/",1,12,1,0,doNothing,noEvent,wrapStyle)
-  ,FIELD(day,"","",1,31,1,0,doNothing,noEvent,wrapStyle)
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-char* constMEM alphaNum MEMMODE=" 0123456789.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,\\|!\"#$%&/()=?~*^+-{}[]€";
-char* constMEM alphaNumMask[] MEMMODE={alphaNum};
-char name[]="                                                  ";
-
-MENU(mainMenu,"Main menu",zZz,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Name",name,alphaNumMask,doNothing,noEvent,noStyle)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,SUBMENU(birthDate)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("press [select]");
-    o.setCursor(0,2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-result idle(menuOut &o, idleEvent e) {
-  // o.clear();
-  switch(e) {
-    case idleStart:o.println("suspending menu!");break;
-    case idling:o.println("suspended...");break;
-    case idleEnd:o.println("resuming menu.");
-      nav.reset();
-      break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(LEDPIN,OUTPUT);
-  digitalWrite(LEDPIN,ledCtrl);
-  delay(500);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");Serial.flush();
-  nav.timeOut=3;
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  // nav.idleOn();//this menu will start on idle state, press select to enter menu
-  //nav.doInput("323");
-  // nav.useAccel=false;
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/TFT/TFT/TFT.ino b/examples/TFT/TFT/TFT.ino
deleted file mode 100644
index a72c93a4..00000000
--- a/examples/TFT/TFT/TFT.ino
+++ /dev/null
@@ -1,100 +0,0 @@
-/********************
-Arduino generic menu system
-Arduino TFT menu example
-Arduino TFT: https://www.arduino.cc/en/Guide/TFT
-
-Sep. 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu on TFT device
-output: ST7735
-input: Serial
-MCU: see TFT library compatibility
-*/
-
-#include <TFT.h> // Hardware-specific library
-#include <SPI.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/tftOut.h>
-
-using namespace Menu;
-
-//display size
-#define TFT_Width 160
-#define TFT_Height 128
-
-//font size plus margins
-#define fontX 6
-#define fontY 9
-
-#define CS   A1
-#define DC   A0
-#define RST  A2
-
-TFT tft(CS, DC, RST);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";//<-- menu will edit this text
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 1
-
-#define ST7735_GRAY RGB565(128,128,128)
-
-const colorDef<uint16_t> colors[] MEMMODE={
-  {{ST7735_BLACK,ST7735_BLACK},{ST7735_BLACK,ST7735_BLUE,ST7735_BLUE}},//bgColor
-  {{ST7735_GRAY,ST7735_GRAY},{ST7735_WHITE,ST7735_WHITE,ST7735_WHITE}},//fgColor
-  {{ST7735_WHITE,ST7735_BLACK},{ST7735_YELLOW,ST7735_YELLOW,ST7735_RED}},//valColor
-  {{ST7735_WHITE,ST7735_BLACK},{ST7735_WHITE,ST7735_YELLOW,ST7735_YELLOW}},//unitColor
-  {{ST7735_WHITE,ST7735_GRAY},{ST7735_BLACK,ST7735_BLUE,ST7735_WHITE}},//cursorColor
-  {{ST7735_WHITE,ST7735_YELLOW},{ST7735_BLUE,ST7735_RED,ST7735_RED}},//titleColor
-};
-
-//initializing output and menu nav without macros
-const panel default_serial_panels[] MEMMODE={{0,0,40,10}};
-navNode* default_serial_nodes[sizeof(default_serial_panels)/sizeof(panel)];
-panelsList default_serial_panel_list(
-  default_serial_panels,
-  default_serial_nodes,
-  sizeof(default_serial_panels)/sizeof(panel)
-);
-
-//define output device
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(*(Print*)&Serial,serialTops);
-
-//define outputs controller
-idx_t ucg_tops[MAX_DEPTH];
-PANELS(ucgPanels,{0,0,TFT_Width/fontX,TFT_Height/fontY});
-TFTOut tftOut(tft,colors,ucg_tops,ucgPanels,fontX,fontY);
-
-menuOut* const outputs[] MEMMODE={&outSerial,&tftOut};//list of output devices
-outputsList out(outputs,2);//outputs list controller
-
-serialIn serial(Serial);
-
-//define navigation root and aux objects
-navNode nav_cursors[MAX_DEPTH];//aux objects to control each level of navigation
-navRoot nav(mainMenu, nav_cursors, MAX_DEPTH, serial, out);
-
-void setup(){
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x");
-  tft.begin();
-  tft.background(0,0,0);  // clear the screen with black
-  tft.setRotation(3);
-  tft.setTextWrap(false);
-  tft.println("Menu 4.x");
-  delay(1000);  // pause for dramatic effect
-}
-
-void loop(){
-  nav.poll();
-}
diff --git a/examples/TFT_HX8257/TFT_HX8257/TFT_HX8257.ino b/examples/TFT_HX8257/TFT_HX8257/TFT_HX8257.ino
deleted file mode 100644
index ef8dcf25..00000000
--- a/examples/TFT_HX8257/TFT_HX8257/TFT_HX8257.ino
+++ /dev/null
@@ -1,225 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Feb.2018 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu with TFT_HX8357 driver https://github.com/Bodmer/TFT_HX8357
-output: not sure yet... ;)
-input: Serial + encoder
-www.r-site.net
-
-alternative encoder (clickEncoder) uses:
-https://github.com/0xPIT/encoder
-https://github.com/PaulStoffregen/TimerOne
-***/
-
-//removed as extra libs are not included into travis
-// #define USE_CLICK_ENCODER
-
-// #include <SPI.h>
-// #include <TFT_HX8357.h> // included by menu driver <menuIO/TFT_HX8357Out.h>
-#include <menu.h>
-#include <menuIO/TFT_HX8357Out.h>
-#define USE_CLICK_ENCODER
-#ifdef USE_CLICK_ENCODER
-  #include <TimerOne.h>
-  #include <ClickEncoder.h>
-  #include <menuIO/clickEncoderIn.h>
-#else
-  #include <menuIO/encoderIn.h>
-#endif
-#include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialIO.h>
-
-using namespace Menu;
-
-#define fontW 16
-#define fontH 16
-
-TFT_HX8357 tft = TFT_HX8357();       // Invoke custom library
-
-#define LEDPIN LED_BUILTIN
-
-// rotary encoder pins
-#define encA    2
-#define encB    3
-#define encBtn  4
-
-result doAlert(eventMask e, prompt &item);
-
-int test=55;
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,altOP(altPrompt,"",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  // ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  //,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-// define menu colors --------------------------------------------------------
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-//monochromatic color table
-
-#define TFT_GREY 0x5AEB
-
-const colorDef<uint16_t> colors[] MEMMODE={
-  {{TFT_BLACK,TFT_BLACK},{TFT_BLACK,TFT_BLUE,TFT_BLUE}},//bgColor
-  {{TFT_GREY,TFT_GREY},{TFT_WHITE,TFT_WHITE,TFT_WHITE}},//fgColor
-  {{TFT_WHITE,TFT_BLACK},{TFT_YELLOW,TFT_YELLOW,TFT_RED}},//valColor
-  {{TFT_WHITE,TFT_BLACK},{TFT_WHITE,TFT_YELLOW,TFT_YELLOW}},//unitColor
-  {{TFT_WHITE,TFT_GREY},{TFT_BLACK,TFT_BLUE,TFT_WHITE}},//cursorColor
-  {{TFT_WHITE,TFT_YELLOW},{TFT_BLUE,TFT_RED,TFT_RED}},//titleColor
-};
-
-serialIn serial(Serial);
-
-#ifdef USE_CLICK_ENCODER
-  ClickEncoder clickEncoder(encA,encB,encBtn);
-  ClickEncoderStream encStream(clickEncoder,1);
-  MENU_INPUTS(in,&encStream,&serial);
-  void timerIsr() {clickEncoder.service();}
-#else
-  encoderIn<encA,encB> encoder;//simple quad encoder driver
-  encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-  //a keyboard with only one key as the encoder button
-  keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-  keyIn<1> encButton(encBtn_map);//1 is the number of keys
-  MENU_INPUTS(in,&encStream,&encButton,&serial);
-#endif
-
-#define MAX_DEPTH 4
-
-//define output device
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(Serial,serialTops);
-
-constMEM panel panels[] MEMMODE={{0,0,480/fontW,320/fontH}};
-navNode* nodes[sizeof(panels)/sizeof(panel)];//navNodes to store navigation status
-panelsList pList(panels,nodes,1);//a list of panels and nodes
-idx_t gfxTops[MAX_DEPTH]={0};
-tftHX8257Out tftOut(tft,colors,gfxTops,pList,fontW,fontH);
-
-//define outputs controller
-menuOut* constMEM outputs[] MEMMODE={&outSerial,&tftOut};//list of output devices
-outputsList out(outputs,2);//outputs list controller
-
-//define navigation root and aux objects
-navNode nav_cursors[MAX_DEPTH];//aux objects to control each level of navigation
-navRoot nav(mainMenu, nav_cursors, MAX_DEPTH, in, out);
-
-// MENU_OUTPUTS(out,MAX_DEPTH
-//   ,ADAGFX_OUT(tft,colors,6*textScale,9*textScale,{0,0,14,8},{14,0,14,8})
-//   ,SERIAL_OUT(Serial)
-// );
-//
-// NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.println(F("suspended..."));
-    o.println(F("press [select]"));
-    o.println(F("to continue"));
-  }
-  return proceed;
-}
-
-//config myOptions('*','-',defaultNavCodes,false);
-
-void setup() {
-  //options=&myOptions;//can customize options
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");
-  Serial.flush();
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  mainMenu[1].disable();
-  //outGfx.usePreview=true;//reserve one panel for preview?
-  //nav.showTitle=false;//show menu title?
-
-  //pinMode(encBtn, INPUT_PULLUP);
-  #ifdef USE_CLICK_ENCODER
-    Timer1.initialize(1000);
-    Timer1.attachInterrupt(timerIsr);
-  #else
-    encButton.begin();
-    encoder.begin();
-  #endif
-
-  //SPI.begin();
-  tft.init();
-  tft.setRotation(1);
-  // tft.setTextSize(textScale);//test scalling
-  // tft.setTextWrap(false);
-  tft.fillScreen(TFT_BLACK);
-  // tft.setTextColor(TFT_RED,TFT_BLACK);
-  tft.println("Menu 4.x test HX8257");
-  delay(1000);
-}
-
-void loop() {
-  nav.poll();//this device only draws when needed
-  digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/TextField/.gitignore b/examples/TextField/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/TextField/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/TextField/.travis.yml b/examples/TextField/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/TextField/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/TextField/TextField/TextField.ino b/examples/TextField/TextField/TextField.ino
deleted file mode 100644
index d5d71838..00000000
--- a/examples/TextField/TextField/TextField.ino
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-//#include <Dump.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-
-//list of allowed characters
-char* const  digit="0123456789";
-char* const hexChars MEMMODE="0123456789ABCDEF";
-char* const alphaNum[] MEMMODE = {" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,+-_"};
-//individual character validators
-char* constMEM validData[] MEMMODE={hexChars,hexChars,hexChars,hexChars};
-
-char* constMEM validIP[] MEMMODE = {"012",digit,digit,"."};
-char buf0[]="000.000.000.000";
-
-//define "Op 0" without macro
-constMEM char op1Text[] MEMMODE="IP";//field name
-constMEM textFieldShadowRaw op1InfoRaw MEMMODE={
-  (callback)doNothing,
-  (Menu::systemStyles)(_noStyle|_canNav|_parentDraw),
-  op1Text,
-  enterEvent,
-  noStyle,
-  buf0,//edit buffer
-  validIP,
-  4//this is the number of entries on validators array, not th efield length
-};//MEMMODE static stuff
-constMEM textFieldShadow& op1Info=*(textFieldShadow*)&op1InfoRaw;//hacking c++ to use progmem (hugly)
-textField option0(op1Info);
-
-char buf1[]="0000";
-char name[]="                              ";//field will initialize its size by this string length
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OBJ(option0)
-  ,EDIT("Hex",buf1,validData,doNothing,noEvent,noStyle)
-  ,EDIT("Name",name,alphaNum,doNothing,noEvent,noStyle)
-  ,EXIT("<Exit")
-);
-
-#define MAX_DEPTH 1
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x text field test");Serial.flush();
-  Serial.println(sizeof(validData)/sizeof(void*));
-  /*Serial.println((uint16_t)buf1,HEX);
-  Serial.println((uint16_t)(*(textField*)&mainMenu[1]).buffer(),HEX);
-  Serial.println((uint16_t)((textFieldShadow*)mainMenu[1].shadow)->buffer,HEX);
-  Serial.println((uint16_t)memPtr(((textFieldShadow*)mainMenu[1].shadow)->buffer),HEX);
-  dumpRam(Serial,buf1,4);
-  dumpPgm(Serial,buf1,4);
-  dumpPgm(Serial,(textFieldShadowRaw*)mainMenu[1].shadow,sizeof(textFieldShadowRaw));*/
-}
-
-void loop() {
-  nav.poll();
-  delay(100);//delay to simulate other tasks
-}
diff --git a/examples/TextField/platformio.ini b/examples/TextField/platformio.ini
deleted file mode 100644
index 30e66d18..00000000
--- a/examples/TextField/platformio.ini
+++ /dev/null
@@ -1,42 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=TextField
-lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
-
-; [env:atmega328_8]
-; platform=atmelavr
-; board=pro8MHzatmega328
-; framework=arduino
-; upload_protocol = usbasp
-; upload_flags = -Pusb
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++
-
-; [env:esp12e]
-; platform = espressif8266
-; board = esp12e
-; framework = arduino
-; upload_speed=921600
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++ -DDEBUG
diff --git a/examples/U8G2/U8G2/U8G2.ino b/examples/U8G2/U8G2/U8G2.ino
deleted file mode 100644
index c6a35a2a..00000000
--- a/examples/U8G2/U8G2/U8G2.ino
+++ /dev/null
@@ -1,258 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Arduino generic menu system
-U8G2 menu example
-U8G2: https://github.com/olikraus/u8g2
-
-Oct. 2016 Stephen Denne https://github.com/datacute
-Based on example from Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Original from: https://github.com/christophepersoz
-
-menu on U8G2 device
-output: Wemos D1 mini OLED Shield (SSD1306 64x48 I2C) + Serial
-input: Serial + encoder
-mcu: nano328p
-
-*/
-
-#include <menu.h>
-#include <menuIO/u8g2Out.h>
-// #include <menuIO/encoderIn.h>
-// #include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-
-// #define USE_PCD8544
-#define USE_SSD1306
-
-#if defined(USE_PCD8544)
-  // rotary encoder pins
-  // #define encA    2
-  // #define encB    3
-  // #define encBtn  4
-
-  #include <SPI.h>
-  #define USE_HWSPI
-  #define U8_DC 9
-  #define U8_CS 8
-  #define U8_RST 7
-  #define fontName u8g2_font_5x7_tf
-  #define fontX 5
-  #define fontY 9
-  #define offsetX 0
-  #define offsetY 0
-  #define U8_Width 84
-  #define U8_Height 48
-  U8G2_PCD8544_84X48_1_4W_HW_SPI u8g2(U8G2_R0, U8_CS, U8_DC , U8_RST);
-#elif defined(USE_SSD1306)
-  // rotary encoder pins
-  // #define encA    5
-  // #define encB    6
-  // #define encBtn  7
-
-  #include <Wire.h>
-  #define fontName u8g2_font_7x13_mf
-  #define fontX 7
-  #define fontY 16
-  #define offsetX 0
-  #define offsetY 3
-  #define U8_Width 128
-  #define U8_Height 64
-  #define USE_HWI2C
-  // U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);//, SCL, SDA);
-  // U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R2, U8X8_PIN_NONE, 4, 5);
-  // U8G2_SSD1306_128X64_VCOMH0_F_HW_I2C u8g2(U8G2_R2, U8X8_PIN_NONE, 4, 5);
-  U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, 4, 5);
-#else
-  #error DEFINE YOUR OUTPUT HERE.
-#endif
-
-
-// define menu colors --------------------------------------------------------
-//each color is in the format:
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-// this is a monochromatic color table
-const colorDef<uint8_t> colors[] MEMMODE={
-  {{0,0},{0,1,1}},//bgColor
-  {{1,1},{1,0,0}},//fgColor
-  {{1,1},{1,0,0}},//valColor
-  {{1,1},{1,0,0}},//unitColor
-  {{0,1},{0,0,1}},//cursorColor
-  {{1,1},{1,0,0}},//titleColor
-};
-
-result doAlert(eventMask e, prompt &item);
-
-int test=55;
-
-int ledCtrl=HIGH;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-// //customizing a prompt look!
-// //by extending the prompt class
-// class altPrompt:public prompt {
-// public:
-//   altPrompt(constMEM promptShadow& p):prompt(p) {}
-//   Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) override {
-//     return out.printRaw(F("special prompt!"),len);;
-//   }
-// };
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,OP("Sub1",doNothing,noEvent)
-  // ,altOP(altPrompt,"",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-uint16_t hrs=0;
-uint16_t mins=0;
-
-//define a pad style menu (single line menu)
-//here with a set of fields to enter a date in YYYY/MM/DD format
-altMENU(menu,time,"Time",doNothing,noEvent,noStyle,(systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
-  ,FIELD(hrs,"",":",0,11,1,0,doNothing,noEvent,noStyle)
-  ,FIELD(mins,"","",0,59,10,1,doNothing,noEvent,wrapStyle)
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  //,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(time)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Exit")
-);
-
-#define MAX_DEPTH 2
-
-// encoderIn<encA,encB> encoder;//simple quad encoder driver
-// encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-
-//a keyboard with only one key as the encoder button
-// keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-// keyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-// menuIn* inputsList[]={&encBuitton,&Serial};
-// chainStream<2> in(inputsList);//1 is the number of inputs
-
-serialIn serial(Serial);
-MENU_INPUTS(in,&serial);
-// MENU_INPUTS(in,&encStream,&encButton);//,&serial);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,U8G2_OUT(u8g2,colors,fontX,fontY,offsetX,offsetY,{0,0,U8_Width/fontX,U8_Height/fontY})
-  ,SERIAL_OUT(Serial)
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("press [select]");
-    o.setCursor(0,2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  o.clear();
-  switch(e) {
-    case idleStart:o.println("suspending menu!");break;
-    case idling:o.println("suspended...");break;
-    case idleEnd:o.println("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");Serial.flush();
-  // encButton.begin();
-  // encoder.begin();
-  // pinMode(LEDPIN,OUTPUT);//cant use pin 13 when using hw spi
-  // and on esp12 i2c can be on pin 2, and that is also led pin
-  // so check first if this is adequate for your board
-  #if defined(USE_HWSPI)
-    SPI.begin();
-    u8g2.begin();
-  #elif defined(USE_HWI2C)
-    Wire.begin();
-    u8g2.begin();
-  #else
-    #error "please choose your interface (I2c,SPI)"
-  #endif
-  u8g2.setFont(fontName);
-  // u8g2.setBitmapMode(0);
-
-  // disable second option
-  mainMenu[1].enabled=disabledStatus;
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  Serial.println("setup done.");Serial.flush();
-}
-
-void loop() {
-  nav.doInput();
-  // digitalWrite(LEDPIN, ledCtrl);
-  if (nav.changed(0)) {//only draw if menu changed for gfx device
-    //change checking leaves more time for other tasks
-    u8g2.firstPage();
-    do nav.doOutput(); while(u8g2.nextPage());
-  }
-  delay(100);//simulate other tasks delay
-}
diff --git a/examples/U8GLib/.gitignore b/examples/U8GLib/.gitignore
deleted file mode 100644
index e05273b2..00000000
--- a/examples/U8GLib/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.clang_complete
-.gcc-flags.json
-.piolibdeps
\ No newline at end of file
diff --git a/examples/U8GLib/.travis.yml b/examples/U8GLib/.travis.yml
deleted file mode 100644
index 72c6e43f..00000000
--- a/examples/U8GLib/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/stable/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/stable/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/stable/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/U8GLib/U8GLib/U8GLib.ino b/examples/U8GLib/U8GLib/U8GLib.ino
deleted file mode 100644
index 44c8b65d..00000000
--- a/examples/U8GLib/U8GLib/U8GLib.ino
+++ /dev/null
@@ -1,242 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Arduino generic menu system
-U8GLib menu example
-U8Glib: https://github.com/olikraus/U8glib_Arduino
-
-Jul.2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Original from: https://github.com/christophepersoz
-
-menu on U8GLib device
-output: Nokia 5110 display (PCD8544 HW SPI) + Serial
-input: Serial + encoder
-
-ESP8266 Compile Error:
-  `.irom0.text' will not fit in region `irom0_0_seg'
-  see: http://bbs.espressif.com/viewtopic.php?t=166
-
-please use U8G2 instead.
-
-*/
-
-#include <U8glib.h>
-#include <menu.h>
-#include <menuIO/encoderIn.h>
-#include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/U8GLibOut.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-
-// rotary encoder pins
-#define encA    2
-#define encB    3
-#define encBtn  4
-
-#define U8_DC 9
-#define U8_CS 8
-#define U8_RST 7
-
-U8GLIB_PCD8544 u8g(U8_CS, U8_DC, U8_RST) ;
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e) {
-  Serial.print(e);
-  Serial.println(" action1 executed, proceed menu");
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e,navNode& nav, prompt &item) {
-  Serial.print(e);
-  Serial.print(" action2 executed, quiting menu");
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EXIT("<Back")
-);
-
-// define menu colors --------------------------------------------------------
-//each color is in the format:
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-// this is a monochromatic color table
-const colorDef<uint8_t> colors[] MEMMODE={
-  {{0,0},{0,1,1}},//bgColor
-  {{1,1},{1,0,0}},//fgColor
-  {{1,1},{1,0,0}},//valColor
-  {{1,1},{1,0,0}},//unitColor
-  {{0,1},{0,0,1}},//cursorColor
-  {{0,0},{1,1,1}},//titleColor
-};
-
-encoderIn<encA,encB> encoder;//simple quad encoder driver
-encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-
-//a keyboard with only one key as the encoder button
-keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, on = low
-keyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-serialIn serial(Serial);
-
-//input from the encoder + encoder button + serial
-menuIn* inputsList[]={&encStream,&encButton,&serial};
-chainStream<3> in(inputsList);//3 is the number of inputs
-
-//fontY should now account for fontMarginY
-#define fontX 6
-#define fontY 9
-#define MAX_DEPTH 2
-
-//this macro replaces all the above commented lines
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,U8GLIB_OUT(u8g,colors,fontX,fontY,{0,0,84/fontX,48/fontY})
-  ,SERIAL_OUT(Serial)
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("press [select]");
-    o.setCursor(0,2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  o.clear();
-  switch(e) {
-    case idleStart:o.println("suspending menu!");break;
-    case idling:o.println("suspended...");break;
-    case idleEnd:o.println("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  mainMenu[1].enabled=disabledStatus;
-  //change input burst for slow output devices
-  //this is the number of max. processed inputs before drawing
-  nav.inputBurst=10;
-
-  pinMode(encBtn, INPUT_PULLUP);
-  encButton.begin();
-  encoder.begin();
-
-  //u8g.setFont(u8g_font_helvR08);
-  u8g.setFont(u8g_font_6x10);
-  //u8g.setFont(u8g_font_04b_03r);
-  u8g.firstPage();
-  do {
-    u8g.setColorIndex(1);
-    nav.out[0].setCursor(0,0);
-    nav.out[0].print(F("Menu 4.x test"));
-    nav.out[0].setCursor(0,1);
-    nav.out[0].print(F("on U8Glib"));
-  } while(u8g.nextPage());
-  delay(1000);
-}
-
-void loop() {
-  nav.doInput();
-  digitalWrite(LEDPIN, ledCtrl);
-  if (nav.changed(0)) {//only draw if menu changed for gfx device
-    //because this code clears the screen, if always called then screen will blink
-    u8g.firstPage();
-    do nav.doOutput(); while(u8g.nextPage());
-  }
-  delay(100);//simulate other tasks delay
-}
diff --git a/examples/U8GLib/platformio.ini b/examples/U8GLib/platformio.ini
deleted file mode 100644
index edca50a4..00000000
--- a/examples/U8GLib/platformio.ini
+++ /dev/null
@@ -1,52 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter, extra scripting
-;   Upload options: custom port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/en/stable/projectconf.html
-
-[platformio]
-src_dir=U8GLib
-; lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-upload_speed=57600
-build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++
-
-; [env:due]
-; platform = atmelsam
-; board = due
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG -DNOTRACE
-
-; [env:esp01_1m]
-; platform = espressif8266
-; board = esp01_1m
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++
-
-; [env:uno]
-; platform = atmelavr
-; board = uno
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++ -DDEBUG
-
-; [env:esp12e]
-; platform = espressif8266
-; board = esp12e
-; framework = arduino
-; upload_speed=921600
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++ -DNODEBUG -DMENU_SSID="\"r-site.net\"" -DMENU_PASS="\"rsite.2011\""
diff --git a/examples/U8x8/U8x8/U8x8.ino b/examples/U8x8/U8x8/U8x8.ino
deleted file mode 100644
index 542bf769..00000000
--- a/examples/U8x8/U8x8/U8x8.ino
+++ /dev/null
@@ -1,106 +0,0 @@
-/********************
-Arduino generic menu system
-U8x8 menu example
-U8x8: https://github.com/olikraus/Ucglib_Arduino
-
-Sep. 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu on U8x8 device
-output: PCD8544 (Nokia 5110)
-input: Serial
-mcu: nano328p
-
-*/
-
-#include <Arduino.h>
-#include <SPI.h>
-#include <Wire.h>
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/U8x8Out.h>
-#include <U8x8lib.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-
-#define U8_DC 9
-#define U8_CS 8
-#define U8_RST 7
-#define U8_Width 84
-#define U8_Height 48
-
-U8X8_PCD8544_84X48_4W_HW_SPI u8x8(U8_CS, U8_DC , U8_RST);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";//<-- menu will edit this text
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,SUBMENU(chooseMenu)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,U8X8_OUT(u8x8,{0,0,10,6})
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-//initializing output and menu nav without macros
-/*const panel default_serial_panels[] MEMMODE={{0,0,40,10}};
-navNode* default_serial_nodes[sizeof(default_serial_panels)/sizeof(panel)];
-panelsList default_serial_panel_list(
-  default_serial_panels,
-  default_serial_nodes,
-  sizeof(default_serial_panels)/sizeof(panel)
-);
-
-//define output device
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(*(Print*)&Serial,serialTops);
-
-//define outputs controller
-idx_t u8x8_tops[MAX_DEPTH];
-PANELS(u8x8Panels,{0,0,U8_Width/8,U8_Height/8});
-U8x8Out u8x8Out(u8x8,u8x8_tops,u8x8Panels);
-
-menuOut* const outputs[] MEMMODE={&outSerial,&u8x8Out};//list of output devices
-outputsList out(outputs,2);//outputs list controller
-
-//define navigation root and aux objects
-navNode nav_cursors[MAX_DEPTH];//aux objects to control each level of navigation
-navRoot nav(mainMenu, nav_cursors, MAX_DEPTH, Serial, out);*/
-
-void setup(void)
-{
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x test");
-  u8x8.begin();
-  u8x8.setFont(u8x8_font_chroma48medium8_r);
-  u8x8.drawString(0,0,"Menu 4.x");
-  delay(1000);
-}
-
-void loop(void)
-{
-  nav.poll();
-  delay(100);
-}
diff --git a/examples/UART/uart_menu/uart_menu.ino b/examples/UART/uart_menu/uart_menu.ino
deleted file mode 100644
index 4bec2d1e..00000000
--- a/examples/UART/uart_menu/uart_menu.ino
+++ /dev/null
@@ -1,97 +0,0 @@
-/********************
-Arduino generic menu system
-
-Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-output: Serial
-input: Serial
-*/
-
-#include <Arduino.h>
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/uartOut.h>
-#include <SoftwareSerial.h>
-
-using namespace Menu;
-
-#define LEDPIN LED_BUILTIN
-
-SoftwareSerial ss(11, 10);
-
-
-#define MAX_DEPTH 2
-
-// define menu colors --------------------------------------------------------
-#define C_BLACK 0
-#define C_BLUE 3
-#define C_GRAY 7
-#define C_WHITE 15
-#define C_YELLOW 31
-#define C_RED 1
-#define C_GREEN 2
-//each color is in the format:
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-const colorDef<uint8_t> colors[] MEMMODE={
-  {{C_BLACK,C_BLACK}, {C_BLACK,C_BLUE,C_BLUE}},//bgColor
-  {{C_GRAY,C_GRAY},   {C_WHITE,C_WHITE,C_WHITE}},//fgColor
-  {{C_WHITE,C_BLACK}, {C_YELLOW,C_YELLOW,C_RED}},//valColor
-  {{C_WHITE,C_BLACK}, {C_WHITE,C_YELLOW,C_YELLOW}},//unitColor
-  {{C_WHITE,C_GRAY},  {C_BLACK,C_BLUE,C_WHITE}},//cursorColor
-  {{C_WHITE,C_YELLOW},{C_GREEN,C_WHITE,C_WHITE}},//titleColor
-};
-
-
-#define offsetX 0
-#define offsetY 0
-#define U8_Width 240
-#define U8_Height 320
-
-#define LEDPIN LED_BUILTIN
-
-
-int timeOn=10;
-int timeOff=90;
-
-MENU(mainMenu, "Settings menu", Menu::doNothing, Menu::noEvent, Menu::wrapStyle
-  ,FIELD(timeOn,"On","ms",0,100,10,1, Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,FIELD(timeOff,"Off","ms",0,100,10,1,Menu::doNothing, Menu::noEvent, Menu::noStyle)
-  ,EXIT("<Back")
-);
-
-serialIn serial(Serial);
-
-MENU_INPUTS(in,&serial);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,UART_OUT(ss,colors,uartOut::systemFont::font24,offsetX,offsetY,{0,0,U8_Width/uartOut::systemFont::font24*2,U8_Height/uartOut::systemFont::font24})
-  ,SERIAL_OUT(Serial)
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-void setup() {
-  pinMode(LEDPIN, OUTPUT);
-  Serial.begin(115200);
-  ss.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x");
-  Serial.println("Use keys + - * /");
-  Serial.println("to control the menu navigation");
-}
-
-void loop() {
-  nav.doInput();
-  if (nav.changed(0)) {
-    //only draw if menu changed for gfx device
-    nav.doOutput();
-  }
-  digitalWrite(LEDPIN, HIGH);
-  delay(timeOn);
-  digitalWrite(LEDPIN, LOW);
-  delay(timeOff);
-}
-
diff --git a/examples/UCGLib/UCGLib/UCGLib.ino b/examples/UCGLib/UCGLib/UCGLib.ino
deleted file mode 100644
index 5e0621f0..00000000
--- a/examples/UCGLib/UCGLib/UCGLib.ino
+++ /dev/null
@@ -1,136 +0,0 @@
-/********************
-Arduino generic menu system
-UCGLib menu example
-UCGLib: https://github.com/olikraus/Ucglib_Arduino
-
-Sep. 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu on UCGLib device
-output: ST7735
-input: Serial
-mcu: nano328p
-*/
-
-#include <SPI.h>
-#include <Ucglib.h>
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/UCGLibOut.h>
-
-using namespace Menu;
-
-#define UC_Width 160
-#define UC_Height 128
-
-#ifdef ESP8266
-  #define UC_CS   2
-  #define UC_DC   3
-  #define UC_RST  4
-#else
-  #define UC_CS   A1
-  #define UC_DC   A0
-  #define UC_RST  A2
-#endif
-
-//font size plus margins
-#define fontX 6
-#define fontY 11
-
-Ucglib_ST7735_18x128x160_HWSPI ucg(UC_DC , UC_CS, UC_RST);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";//<-- menu will edit this text
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,SUBMENU(chooseMenu)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-//define colors
-#define BLACK {0,0,0}
-#define BLUE {0,0,255}
-#define GRAY {128,128,128}
-#define WHITE {255,255,255}
-#define YELLOW {255,255,0}
-#define RED {255,0,0}
-
-const colorDef<rgb> colors[] MEMMODE={
-  {{BLACK,BLACK},{BLACK,BLUE,BLUE}},//bgColor
-  {{GRAY,GRAY},{WHITE,WHITE,WHITE}},//fgColor
-  {{WHITE,BLACK},{YELLOW,YELLOW,RED}},//valColor
-  {{WHITE,BLACK},{WHITE,YELLOW,YELLOW}},//unitColor
-  {{WHITE,GRAY},{BLACK,BLUE,WHITE}},//cursorColor
-  {{WHITE,YELLOW},{BLUE,RED,RED}},//titleColor
-};
-
-#define offsetX 0
-#define offsetY 0
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,UCG_OUT(ucg,colors,fontX,fontY,offsetX,offsetY,{0,0,UC_Width/fontX,UC_Height/fontY})
-  ,SERIAL_OUT(Serial)
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-//initializing output and menu nav without macros
-/*const panel default_serial_panels[] MEMMODE={{0,0,40,10}};
-navNode* default_serial_nodes[sizeof(default_serial_panels)/sizeof(panel)];
-panelsList default_serial_panel_list(
-  default_serial_panels,
-  default_serial_nodes,
-  sizeof(default_serial_panels)/sizeof(panel)
-);
-
-//define output device
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(*(Print*)&Serial,serialTops);
-
-//define outputs controller
-idx_t ucg_tops[MAX_DEPTH];
-PANELS(ucgPanels,{0,0,UC_Width/fontX,UC_Height/fontY});
-UCGLibOut ucgOut(ucg,colors,ucg_tops,ucgPanels,fontX,fontY);
-
-menuOut* const outputs[] MEMMODE={&outSerial,&ucgOut};//list of output devices
-outputsList out(outputs,2);//outputs list controller
-
-//define navigation root and aux objects
-navNode nav_cursors[MAX_DEPTH];//aux objects to control each level of navigation
-navRoot nav(mainMenu, nav_cursors, MAX_DEPTH, Serial, out);*/
-
-void setup(void)
-{
-  Serial.begin(115200);
-  while(!Serial);
-  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
-  ucg.clearScreen();
-  ucg.setFont(ucg_font_courB08_tr);//choose fized width font (monometric)
-  ucg.setRotate90();
-  ucg.setColor(255,255,255);
-  ucg.setFontPosTop();
-  ucg.print("Menu 4.x ucg");
-  delay(1000);
-  ucg.clearScreen();
-  ucg.setRotate90();
-  ucg.setFontPosBottom();
-}
-
-void loop(void)
-{
-  nav.poll();
-}
diff --git a/examples/UTFT/.gitignore b/examples/UTFT/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/UTFT/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/UTFT/.travis.yml b/examples/UTFT/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/UTFT/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/UTFT/UTFT/UTFT.ino b/examples/UTFT/UTFT/UTFT.ino
deleted file mode 100644
index bbaf1a42..00000000
--- a/examples/UTFT/UTFT/UTFT.ino
+++ /dev/null
@@ -1,212 +0,0 @@
-/********************
-Sept. 2014 ~ Oct 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu with UTFT (tested on arduino due)
-output: 3.2″ TFT LCD Module Display 240X320
-input: Serial + Touch Panel
-www.r-site.net
-
-UTFT library from:
-  http://www.rinkydinkelectronics.com/library.php?id=51
-  http://www.rinkydinkelectronics.com/library.php?id=92
-
-Note: I was unable to build for esp8266 - neu-rah
-***/
-
-#include <Arduino.h>
-#include <menu.h>
-#include <menuIO/utftOut.h>
-#include <menuIO/urtouchIn.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/chainStream.h>
-
-using namespace Menu;
-
-UTFT tft(CTE28,25,26,27,28);
-//extern uint8_t SmallFont[];
-extern uint8_t BigFont[];
-//extern uint8_t SevenSegNumFont[];
-
-#define LEDPIN 13
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e) {
-  Serial.print(e);
-  Serial.println(" action1 executed, proceed menu");Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e,navNode& nav, prompt &item) {
-  Serial.print(e);
-  Serial.println(" action2 executed, quiting menu");
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,noStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,noStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EXIT("<Back")
-);
-
-// define menu colors --------------------------------------------------------
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-//monochromatic color table
-
-const colorDef<uint16_t> colors[] MEMMODE={
-  {{VGA_BLACK,VGA_BLACK},{VGA_BLACK,VGA_BLUE,VGA_BLUE}},//bgColor
-  {{VGA_GRAY,VGA_GRAY},{VGA_WHITE,VGA_WHITE,VGA_WHITE}},//fgColor
-  {{VGA_WHITE,VGA_BLACK},{VGA_YELLOW,VGA_YELLOW,VGA_RED}},//valColor
-  {{VGA_WHITE,VGA_BLACK},{VGA_WHITE,VGA_YELLOW,VGA_YELLOW}},//unitColor
-  {{VGA_WHITE,VGA_GRAY},{VGA_BLACK,VGA_BLUE,VGA_WHITE}},//cursorColor
-  {{VGA_WHITE,VGA_YELLOW},{VGA_BLUE,VGA_RED,VGA_RED}},//titleColor
-};
-
-//PANELS(serial_panels,{0,0,40,10});//or use default
-//serialOut outSerial(Serial);//,serial_panels);//the output device (just the serial port)
-
-#define MAX_DEPTH 2
-
-PANELS(gfx_panels,{0,0,12,8},{13,0,12,8});
-idx_t gfx_tops[MAX_DEPTH];
-utftOut outGfx(tft,colors,gfx_tops,gfx_panels,16,16);//output device, latter set resolution from font measure
-
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(Serial,serialTops);
-MENU_OUTLIST(out,&outGfx,&outSerial);
-
-extern navRoot nav;
-URTouch  uTouch( 6, 5, 4, 3, 2);
-menuUTouch touchPanel(uTouch,nav,outGfx);
-serialIn serial(Serial);
-MENU_INPUTS(in,&touchPanel,&serial);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setColor(fgColor);
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("press [select]");
-    o.setCursor(0,2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setColor(fgColor);
-    o.println("suspended...");
-    o.println("press [select]");
-    o.println("to continue");
-    o.println(millis()%1000);
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(LEDPIN,OUTPUT);
-  while(!Serial);
-  Serial.begin(115200);
-  Serial.println("menu 4.x UTFT + URTouch");Serial.flush();
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  //mainMenu[1].enabled=disabledStatus;
-
-  tft.InitLCD();
-  tft.setBrightness(4);
-  tft.clrScr();
-
-  uTouch.InitTouch();
-  uTouch.setPrecision(PREC_MEDIUM);//LOW, MEDIUM, HI, EXTREME
-
-  tft.setFont(BigFont);
-  tft.setColor(0, 255, 0);
-  tft.setBackColor(0, 0, 0);
-
-  //outGfx.resX=tft.getFontXsize()+1;
-  //outGfx.resY=tft.getFontYsize()+1;
-  outGfx.println("Menu 4.x on UTFT");
-  delay(1000);
-  tft.clrScr();
-}
-
-void loop() {
-  nav.poll();//this device only draws when needed
-  digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/UTFT/platformio.ini b/examples/UTFT/platformio.ini
deleted file mode 100644
index 98119fd2..00000000
--- a/examples/UTFT/platformio.ini
+++ /dev/null
@@ -1,36 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=UTFT
-; lib_dir=~/Arduino/Libraries
-
-[env:due]
-platform = atmelsam
-board = due
-framework = arduino
-build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined
-
-; [env:teensy31]
-; platform=teensy
-; board=teensy31
-; framework=arduino
-
-; [env:nanoatmega328]
-; platform=atmelavr
-; board=nanoatmega328
-; framework=arduino
-
-; [env:esp12e]
-; platform = espressif8266
-; board = esp12e
-; framework = arduino
-; upload_speed=921600
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++ -DDEBUG
diff --git a/examples/adafruitGfx/eTFT/TFT_eSPI/TFT_eSPI.ino b/examples/adafruitGfx/eTFT/TFT_eSPI/TFT_eSPI.ino
deleted file mode 100644
index d0a55ce9..00000000
--- a/examples/adafruitGfx/eTFT/TFT_eSPI/TFT_eSPI.ino
+++ /dev/null
@@ -1,188 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Sept. 2014 ~ Jan 2019 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-TFT_eSPI example
-output: TFT_eSPI + Serial
-input: Serial
-www.r-site.net
-***/
-
-#include <TFT_eSPI.h>
-
-#include <menu.h>
-#include <menuIO/serialIO.h>
-#include <menuIO/TFT_eSPIOut.h>
-// #include <menuIO/chainStream.h>
-#include <menuIO/esp8266Out.h>//must include this even if not doing web output...
-
-using namespace Menu;
-
-TFT_eSPI gfx;
-
-result doAlert(eventMask e, prompt &item);
-
-int test=55;
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,altOP(altPrompt,"",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  // ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  //,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-// define menu colors --------------------------------------------------------
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-//monochromatic color table
-
-
-#define Black RGB565(0,0,0)
-#define Red	RGB565(255,0,0)
-#define Green RGB565(0,255,0)
-#define Blue RGB565(0,0,255)
-#define Gray RGB565(128,128,128)
-#define LighterRed RGB565(255,150,150)
-#define LighterGreen RGB565(150,255,150)
-#define LighterBlue RGB565(150,150,255)
-#define DarkerRed RGB565(150,0,0)
-#define DarkerGreen RGB565(0,150,0)
-#define DarkerBlue RGB565(0,0,150)
-#define Cyan RGB565(0,255,255)
-#define Magenta RGB565(255,0,255)
-#define Yellow RGB565(255,255,0)
-#define White RGB565(255,255,255)
-
-const colorDef<uint16_t> colors[] MEMMODE={
-  {{(uint16_t)Black,(uint16_t)Black}, {(uint16_t)Black, (uint16_t)Blue,  (uint16_t)Blue}},//bgColor
-  {{(uint16_t)Gray, (uint16_t)Gray},  {(uint16_t)White, (uint16_t)White, (uint16_t)White}},//fgColor
-  {{(uint16_t)White,(uint16_t)Black}, {(uint16_t)Yellow,(uint16_t)Yellow,(uint16_t)Red}},//valColor
-  {{(uint16_t)White,(uint16_t)Black}, {(uint16_t)White, (uint16_t)Yellow,(uint16_t)Yellow}},//unitColor
-  {{(uint16_t)White,(uint16_t)Gray},  {(uint16_t)Black, (uint16_t)Blue,  (uint16_t)White}},//cursorColor
-  {{(uint16_t)White,(uint16_t)Yellow},{(uint16_t)Blue,  (uint16_t)Red,   (uint16_t)Red}},//titleColor
-};
-
-#define MAX_DEPTH 4
-
-serialIn serial(Serial);
-
-//MENU_INPUTS(in,&serial);its single, no need to `chainStream`
-
-//define serial output device
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(Serial,serialTops);
-
-#define GFX_WIDTH 128
-#define GFX_HEIGHT 64
-#define fontW 6
-#define fontH 9
-
-constMEM panel panels[] MEMMODE = {{0, 0, GFX_WIDTH / fontW, GFX_HEIGHT / fontH}};
-navNode* nodes[sizeof(panels) / sizeof(panel)]; //navNodes to store navigation status
-panelsList pList(panels, nodes, 1); //a list of panels and nodes
-idx_t eSpiTops[MAX_DEPTH]={0};
-TFT_eSPIOut eSpiOut(gfx,colors,eSpiTops,pList,fontW,fontH+1);
-menuOut* constMEM outputs[] MEMMODE={&outSerial,&eSpiOut};//list of output devices
-outputsList out(outputs,sizeof(outputs)/sizeof(menuOut*));//outputs list controller
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.println(F("suspended..."));
-    o.println(F("press [select]"));
-    o.println(F("to continue"));
-  }
-  return proceed;
-}
-
-//config myOptions('*','-',defaultNavCodes,false);
-
-void setup() {
-  //options=&myOptions;//can customize options
-  // pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");
-  Serial.flush();
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  mainMenu[1].disable();
-  //outGfx.usePreview=true;//reserve one panel for preview?
-  //nav.showTitle=false;//show menu title?
-
-  SPI.begin();
-  gfx.init();
-  gfx.setRotation(3);
-  // gfx.setTextSize(textScale);//test scalling
-  gfx.setTextWrap(false);
-  gfx.fillScreen(Black);
-  gfx.setTextColor(Red,Black);
-  gfx.println("Menu 4.x test on GFX");
-  delay(1000);
-}
-
-void loop() {
-  nav.poll();//this device only draws when needed
-  // digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/adafruitGfx/lcdMono/.gitignore b/examples/adafruitGfx/lcdMono/.gitignore
deleted file mode 100644
index e05273b2..00000000
--- a/examples/adafruitGfx/lcdMono/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.clang_complete
-.gcc-flags.json
-.piolibdeps
\ No newline at end of file
diff --git a/examples/adafruitGfx/lcdMono/.travis.yml b/examples/adafruitGfx/lcdMono/.travis.yml
deleted file mode 100644
index 72c6e43f..00000000
--- a/examples/adafruitGfx/lcdMono/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/stable/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/stable/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/stable/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/adafruitGfx/lcdMono/lcdMono/lcdMono.ino b/examples/adafruitGfx/lcdMono/lcdMono/lcdMono.ino
deleted file mode 100644
index c29c6308..00000000
--- a/examples/adafruitGfx/lcdMono/lcdMono/lcdMono.ino
+++ /dev/null
@@ -1,210 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Sept. 2014 ~ Oct 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu with adafruit GFX
-output: Nokia 5110 display (PCD8544 HW SPI) + Serial
-input: Encoder + Serial
-www.r-site.net
-
-***/
-
-#include <SPI.h>
-#include <Adafruit_GFX.h>
-#include <Adafruit_PCD8544.h>
-#include <menu.h>
-#include <menuIO/encoderIn.h>
-#include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/adafruitGfxOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-//PCD8544 aka nokia5110
-#define GFX_DC  9
-#define GFX_CS  8
-#define GFX_RST 7
-
-Adafruit_PCD8544 gfx(GFX_DC,GFX_CS,GFX_RST);
-
-#define LEDPIN A3
-
-// rotary encoder pins
-#define encA    2
-#define encB    3
-#define encBtn  4
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print(F("event:"));
-  Serial.print(e);
-  return proceed;
-}
-
-int test=55;
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-result alert(menuOut& o,idleEvent e);
-result doAlert(eventMask e, prompt &item);
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-// define menu colors --------------------------------------------------------
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-//monochromatic color table
-const colorDef<uint16_t> colors[] MEMMODE={
-  {{WHITE,BLACK},{WHITE,BLACK,BLACK}},//bgColor
-  {{BLACK,WHITE},{BLACK,WHITE,WHITE}},//fgColor
-  {{BLACK,WHITE},{BLACK,WHITE,WHITE}},//valColor
-  {{BLACK,WHITE},{BLACK,WHITE,WHITE}},//unitColor
-  {{BLACK,WHITE},{WHITE,WHITE,WHITE}},//cursorColor
-  {{BLACK,WHITE},{WHITE,BLACK,BLACK}},//titleColor
-};
-
-#define gfxWidth 84
-#define gfxHeight 48
-#define fontX 6
-//5
-#define fontY 9
-#define MAX_DEPTH 2
-
-encoderIn<encA,encB> encoder;//simple quad encoder driver
-encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-
-//a keyboard with only one key as the encoder button
-keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-keyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-serialIn serial(Serial);
-MENU_INPUTS(in,&encStream,&encButton,&serial);
-
-#define MAX_DEPTH 2
-#define textScale 1
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,ADAGFX_OUT(gfx,colors,fontX,fontY,{0,0,gfxWidth/fontX,gfxHeight/fontY})
-  ,SERIAL_OUT(Serial)
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-//initializing output and menu nav without macros
-/*const panel default_serial_panels[] MEMMODE={{0,0,40,10}};
-navNode* default_serial_nodes[sizeof(default_serial_panels)/sizeof(panel)];
-panelsList default_serial_panel_list(
-  default_serial_panels,
-  default_serial_nodes,
-  sizeof(default_serial_panels)/sizeof(panel)
-);
-
-//define output device
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(*(Print*)&Serial,serialTops);
-
-//define outputs controller
-idx_t gfx_tops[MAX_DEPTH];
-PANELS(gfxPanels,{0,0,gfxWidth/fontX,gfxHeight/fontY});
-adaGfxOut adaOut(gfx,colors,gfx_tops,gfxPanels);
-
-menuOut* const outputs[] MEMMODE={&outSerial,&adaOut};//list of output devices
-outputsList out(outputs,2);//outputs list controller
-
-//define input device
-serialIn serial(Serial);
-
-//define navigation root and aux objects
-navNode nav_cursors[MAX_DEPTH];//aux objects to control each level of navigation
-navRoot nav(mainMenu, nav_cursors, MAX_DEPTH, serial, out);*/
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print(F("alert test"));
-    o.setCursor(0,1);
-    o.print(F("press [select]"));
-    o.setCursor(0,2);
-    o.print(F("to continue..."));
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  o.setCursor(0,0);
-  o.print(F("suspended..."));
-  o.setCursor(0,1);
-  o.print(F("press [select]"));
-  o.setCursor(0,2);
-  o.print(F("to continue"));
-  return proceed;
-}
-
-void setup() {
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println(F("menu 4.x test"));
-  Serial.flush();
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-
-  encButton.begin();
-  encoder.begin();
-
-  SPI.begin();
-  gfx.begin();
-  gfx.clearDisplay();
-  gfx.println(F("Menu 4.x test on GFX"));
-  gfx.setContrast(50);
-  gfx.display(); // show splashscreen
-  delay(2000);
-  gfx.clearDisplay();
-  gfx.display(); // show splashscreen
-  // gfx.drawRect(0, 0, 84, 48, 1);
-}
-
-void loop() {
-  //nav.poll();//it can work like this, followed by the gfx.display()
-  //gfx.display();
-
-  //or on a need to draw basis:
-  nav.doInput();
-  if (nav.changed(0)) {//only draw if changed
-    nav.doOutput();
-    gfx.display();
-  }
-
-  digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/adafruitGfx/lcdMono/platformio.ini b/examples/adafruitGfx/lcdMono/platformio.ini
deleted file mode 100644
index fc3e93bc..00000000
--- a/examples/adafruitGfx/lcdMono/platformio.ini
+++ /dev/null
@@ -1,25 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter, extra scripting
-;   Upload options: custom port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/en/stable/projectconf.html
-
-[platformio]
-src_dir=lcdMono
-; lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform=atmelavr
-board=nanoatmega328
-framework=arduino
-upload_flags=-V
-build_flags = -DNO_DEBUG -DNO_MENU_ASYNC
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -Wno-switch
diff --git a/examples/adafruitGfx/tft/.gitignore b/examples/adafruitGfx/tft/.gitignore
deleted file mode 100644
index e05273b2..00000000
--- a/examples/adafruitGfx/tft/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.clang_complete
-.gcc-flags.json
-.piolibdeps
\ No newline at end of file
diff --git a/examples/adafruitGfx/tft/.travis.yml b/examples/adafruitGfx/tft/.travis.yml
deleted file mode 100644
index 72c6e43f..00000000
--- a/examples/adafruitGfx/tft/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/stable/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/stable/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/stable/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/adafruitGfx/tft/platformio.ini b/examples/adafruitGfx/tft/platformio.ini
deleted file mode 100644
index deb28f5b..00000000
--- a/examples/adafruitGfx/tft/platformio.ini
+++ /dev/null
@@ -1,26 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter, extra scripting
-;   Upload options: custom port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/en/stable/projectconf.html
-
-[platformio]
-src_dir=tft
-; lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -DNODEBUG
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -Wno-switch
diff --git a/examples/adafruitGfx/tft/tft/tft.ino b/examples/adafruitGfx/tft/tft/tft.ino
deleted file mode 100644
index 5907caa8..00000000
--- a/examples/adafruitGfx/tft/tft/tft.ino
+++ /dev/null
@@ -1,210 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Sept. 2014 ~ Oct 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu with adafruit GFX
-output: 1.8" TFT 128*160 (ST7735 HW SPI)
-input: Serial + encoder
-www.r-site.net
-
-alternative encoder (clickEncoder) uses:
-https://github.com/0xPIT/encoder
-https://github.com/PaulStoffregen/TimerOne
-***/
-
-//removed as extra libs are not included into travis
-// #define USE_CLICK_ENCODER
-
-#include <SPI.h>
-#include <Adafruit_GFX.h>
-#include <Adafruit_ST7735.h>
-#include <menu.h>
-#include <menuIO/adafruitGfxOut.h>
-#ifdef USE_CLICK_ENCODER
-  #include <TimerOne.h>
-  #include <ClickEncoder.h>
-  #include <menuIO/clickEncoderIn.h>
-#else
-  #include <menuIO/encoderIn.h>
-#endif
-#include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-//ST7735 1.8TFT 128x160
-#define TFT_CS   A1
-#define TFT_DC   A0
-#define TFT_RST  A2
-
-Adafruit_ST7735 gfx(TFT_CS, TFT_DC, TFT_RST);
-
-#define LEDPIN A3
-
-// rotary encoder pins
-#define encA    2
-#define encB    3
-#define encBtn  4
-
-result doAlert(eventMask e, prompt &item);
-
-int test=55;
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,altOP(altPrompt,"",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  // ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  //,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-// define menu colors --------------------------------------------------------
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-//monochromatic color table
-
-#define ST7735_GRAY RGB565(128,128,128)
-
-const colorDef<uint16_t> colors[] MEMMODE={
-  {{(uint16_t)ST7735_BLACK,(uint16_t)ST7735_BLACK}, {(uint16_t)ST7735_BLACK, (uint16_t)ST7735_BLUE,  (uint16_t)ST7735_BLUE}},//bgColor
-  {{(uint16_t)ST7735_GRAY, (uint16_t)ST7735_GRAY},  {(uint16_t)ST7735_WHITE, (uint16_t)ST7735_WHITE, (uint16_t)ST7735_WHITE}},//fgColor
-  {{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_BLACK}, {(uint16_t)ST7735_YELLOW,(uint16_t)ST7735_YELLOW,(uint16_t)ST7735_RED}},//valColor
-  {{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_BLACK}, {(uint16_t)ST7735_WHITE, (uint16_t)ST7735_YELLOW,(uint16_t)ST7735_YELLOW}},//unitColor
-  {{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_GRAY},  {(uint16_t)ST7735_BLACK, (uint16_t)ST7735_BLUE,  (uint16_t)ST7735_WHITE}},//cursorColor
-  {{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_YELLOW},{(uint16_t)ST7735_BLUE,  (uint16_t)ST7735_RED,   (uint16_t)ST7735_RED}},//titleColor
-};
-
-serialIn serial(Serial);
-
-#ifdef USE_CLICK_ENCODER
-  ClickEncoder clickEncoder(encA,encB,encBtn);
-  ClickEncoderStream encStream(clickEncoder,1);
-  MENU_INPUTS(in,&encStream,&serial);
-  void timerIsr() {clickEncoder.service();}
-#else
-  encoderIn<encA,encB> encoder;//simple quad encoder driver
-  encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-  //a keyboard with only one key as the encoder button
-  keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-  keyIn<1> encButton(encBtn_map);//1 is the number of keys
-  MENU_INPUTS(in,&encStream,&encButton,&serial);
-#endif
-
-#define MAX_DEPTH 4
-#define textScale 1
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,ADAGFX_OUT(gfx,colors,6*textScale,9*textScale,{0,0,14,8},{14,0,14,8})
-  ,SERIAL_OUT(Serial)
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.println(F("suspended..."));
-    o.println(F("press [select]"));
-    o.println(F("to continue"));
-  }
-  return proceed;
-}
-
-//config myOptions('*','-',defaultNavCodes,false);
-
-void setup() {
-  //options=&myOptions;//can customize options
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");
-  Serial.flush();
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  mainMenu[1].disable();
-  //outGfx.usePreview=true;//reserve one panel for preview?
-  //nav.showTitle=false;//show menu title?
-
-  //pinMode(encBtn, INPUT_PULLUP);
-  #ifdef USE_CLICK_ENCODER
-    Timer1.initialize(1000);
-    Timer1.attachInterrupt(timerIsr);
-  #else
-    encButton.begin();
-    encoder.begin();
-  #endif
-
-  SPI.begin();
-  gfx.initR(INITR_BLACKTAB);
-  gfx.setRotation(3);
-  gfx.setTextSize(textScale);//test scalling
-  gfx.setTextWrap(false);
-  gfx.fillScreen(ST7735_BLACK);
-  gfx.setTextColor(ST7735_RED,ST7735_BLACK);
-  gfx.println("Menu 4.x test on GFX");
-  delay(1000);
-}
-
-void loop() {
-  nav.poll();//this device only draws when needed
-  digitalWrite(LEDPIN, ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/adafruitGfx/tft_interrupt/tft_interrupt.ino b/examples/adafruitGfx/tft_interrupt/tft_interrupt.ino
deleted file mode 100644
index 3bfc881c..00000000
--- a/examples/adafruitGfx/tft_interrupt/tft_interrupt.ino
+++ /dev/null
@@ -1,295 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Sept. 2014 ~ Oct 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Oct. 2018 - modified by Kevin O'rourke to use interrupts on pins for the sam3x
-
-menu with the newer adafruit GFX
-output: 1.8" TFT 128*160 (ST7735 HW SPI) or
-output: 1.8" TFT 128*160 (ST7735 SOFT SPI)
-
-input: Serial + interrupts
-www.r-site.net
-
-***/
-
-//removed as extra libs are not included into travis
-// #define USE_CLICK_ENCODER
-#define USE_INTERRUPT_PINS // using a joy button
-#define DONT_SHOW_SUSPEND // dont show the suspended screen
-
-#include <Adafruit_GFX.h>
-#include <Adafruit_SPITFT.h>
-#include <Adafruit_ST7735.h>
-#include <menu.h>
-#include <menuIO/adafruitGfxOut.h>
-#ifndef USE_INTERRUPT_PINS
-  #ifdef USE_CLICK_ENCODER
-    #include <TimerOne.h>
-    #include <ClickEncoder.h>
-    #include <menuIO/clickEncoderIn.h>
-  #else
-    #include <menuIO/encoderIn.h>
-  #endif
-  #include <menuIO/keyIn.h>
-  #include <menuIO/chainStream.h>
-  #include <menuIO/serialOut.h>
-  #include <menuIO/serialIn.h>
-#else
-  #include <menuIO/interruptPins.h>
-  #include <menuIO/chainStream.h>
-  #include <menuIO/serialOut.h>
-  #include <menuIO/serialIn.h>
-
-#endif
-
-
-using namespace Menu;
-
-//ST7735 1.8TFT 128x160
-//#define TFT_CS   A1
-//#define TFT_DC   A0
-//#define TFT_RST  A2
-
-
-
-void wait_for(uint32_t  wait) {
-  uint64_t  myMillis = wait * 11986;   // approx 11986000 nop nop per sec
-  for (uint64_t  Counting = 0; Counting <= myMillis; Counting++) {
-    __asm__("nop\n\t");
-  }
-}
-
-
-#define SPI_SCK   13
-#define SPI_DI    12
-#define SPI_DO    11
-#define TFT_CS    15
-#define TFT_RST    0
-#define TFT_DC     8
-
-//Adafruit_ST7735 gfx(TFT_CS, TFT_DC, TFT_RST); // hardware if possible
-
-Adafruit_ST7735 gfx = Adafruit_ST7735(TFT_CS, TFT_DC, SPI_DO, SPI_SCK, TFT_RST);// software spi on the due
-
-#define LEDPIN LED_BUILTIN
-
-#ifndef USE_INTERRUPT_PINS
-  // rotary encoder pins
-  #define encA    2
-  #define encB    3
-  #define encBtn  4
-#else
-  // interrupt pins sam3x with joy button
-  #define BTN_UP     2
-  #define BTN_DOWN   3
-  #define BTN_SEL    5
-  #define BTN_LEFT   6
-  #define BTN_RIGHT  7  
-#endif
-
-result doAlert(eventMask e, prompt &item);
-
-int test=55;
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class confirmExit:public menu {
-public:
-  confirmExit(constMEM menuNodeShadow& shadow):menu(shadow) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t p) override {
-      if(idx<0){menu::printTo(root,sel,out,idx,len,p);}
-      else{out.printRaw((constText*)F("Exit"),len);}
-      return idx;
-  }
-};
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-result systemExit();
-altMENU(confirmExit,subMenu2,"Exit?",doNothing,noEvent,wrapStyle,(Menu::_menuData|Menu::_canNav)
-  ,OP("Yes",systemExit,enterEvent)
-  ,EXIT("Cancel")
-);
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,altOP(altPrompt,"",doNothing,noEvent)
-  ,OP("Op",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  //,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  //,EXIT("<Back")
-  ,SUBMENU(subMenu2)
-);
-
-// define menu colors --------------------------------------------------------
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-//monochromatic color table
-
-#define ST7735_GRAY RGB565(128,128,128)
-
-const colorDef<uint16_t> colors[] MEMMODE={
-  {{ST7735_BLACK,ST7735_BLACK},{ST7735_BLACK,ST7735_BLUE,ST7735_BLUE}},//bgColor
-  {{ST7735_GRAY,ST7735_GRAY},{ST7735_WHITE,ST7735_WHITE,ST7735_WHITE}},//fgColor
-  {{ST7735_WHITE,ST7735_BLACK},{ST7735_YELLOW,ST7735_YELLOW,ST7735_RED}},//valColor
-  {{ST7735_WHITE,ST7735_BLACK},{ST7735_WHITE,ST7735_YELLOW,ST7735_YELLOW}},//unitColor
-  {{ST7735_WHITE,ST7735_GRAY},{ST7735_BLACK,ST7735_BLUE,ST7735_WHITE}},//cursorColor
-  {{ST7735_WHITE,ST7735_YELLOW},{ST7735_BLUE,ST7735_RED,ST7735_RED}},//titleColor
-};
-
-serialIn serial(Serial);
-
-#ifndef USE_INTERRUPT_PINS
-  #ifdef USE_CLICK_ENCODER
-    ClickEncoder clickEncoder(encA,encB,encBtn);
-    ClickEncoderStream encStream(clickEncoder,1);
-    MENU_INPUTS(in,&encStream,&serial);
-    void timerIsr() {clickEncoder.service();}
-  #else
-    encoderIn<encA,encB> encoder;//simple quad encoder driver
-    encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-    //a keyboard with only one key as the encoder button
-    keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-    keyIn<1> encButton(encBtn_map);//1 is the number of keys
-    MENU_INPUTS(in,&encStream,&encButton,&serial);
-  #endif
-#else
-  encoderIn<BTN_UP,BTN_DOWN,BTN_SEL,BTN_LEFT,BTN_RIGHT> encoder;//simple quad encoder driver
-  encoderInStream<BTN_UP,BTN_DOWN,BTN_SEL,BTN_LEFT,BTN_RIGHT> encStream(encoder);// simple quad encoder fake Stream
-  MENU_INPUTS(in,&encStream,&serial);
-#endif
-
-#define MAX_DEPTH 4
-#define textScale 1
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,ADAGFX_OUT(gfx,colors,6*textScale,9*textScale,{0,0,14,8},{14,0,14,8})
-  ,SERIAL_OUT(Serial)
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-#ifndef DONT_SHOW_SUSPEND 
-  if (e==idling) {
-    o.println(F("suspended..."));
-    o.println(F("press [select]"));
-    o.println(F("to continue"));
-  }
-#endif  
-  return proceed;
-}
-
-result systemExit() {
-  encoder.menu_running = false;//prevents the menu from running again!
-  nav.reset();
-  nav.idleOn();//suspend the menu system
-  gfx.fillScreen(ST7735_BLACK);
-  return quit;
-}
-//config myOptions('*','-',defaultNavCodes,false);
-
-void setup() {
-  //options=&myOptions;//can customize options
-  pinMode(LEDPIN,OUTPUT);
-  Serial.begin(211000);
-  while(!Serial);
-  Serial.println("menu 4.x test");
-  Serial.flush();
-
-  //outGfx.usePreview=true;//reserve one panel for preview?
-  //nav.showTitle=false;//show menu title?
-
-  //pinMode(encBtn, INPUT_PULLUP);
-#ifndef USE_INTERRUPT_PINS  
-  #ifdef USE_CLICK_ENCODER
-    Timer1.initialize(1000);
-    Timer1.attachInterrupt(timerIsr);
-  #else
-    encButton.begin();
-    encoder.begin();
-  #endif
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-#else
-  encoder.begin();
-  nav.idleOn(); // suspend the menu system
-#endif
-  mainMenu[0].disable();
-  SPI.begin();
-  gfx.initR(INITR_BLACKTAB);
-  gfx.setRotation(3);
-  gfx.setTextSize(textScale);//test scalling
-  gfx.setTextWrap(false);
-  gfx.fillScreen(ST7735_BLACK);
-  gfx.setTextColor(ST7735_RED,ST7735_BLACK);
-  gfx.println("Menu 4.x test on GFX");
-  delay(2000);
-  gfx.fillScreen(ST7735_BLACK);
-}
-
-void loop() {
-
-#ifndef USE_INTERRUPT_PINS
-   nav.poll();//this device only draws when needed
-   delay(100);//simulate a delay when other tasks are done
-#else
- if((encoder.menu_running)&&(encoder.menu_interrupt)){
-   encoder.menu_interrupt = false;
-   nav.doInput();
-   nav.doOutput(); 
-   }
-#endif
-  digitalWrite(LEDPIN, ledCtrl);
-}
diff --git a/examples/ajoy/ajoy/ajoy.ino b/examples/ajoy/ajoy/ajoy.ino
deleted file mode 100644
index 573902b2..00000000
--- a/examples/ajoy/ajoy/ajoy.ino
+++ /dev/null
@@ -1,80 +0,0 @@
-/********************
-Arduino generic menu system
-
-Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-output: Serial
-input: Analog Joystick + Serial
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/analogAxisIn.h>
-#include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-
-using namespace Menu;
-
-#ifdef ESP8266
-  #define JOY_X 2
-  #define JOY_Y 3
-  #define JOY_BTN 4
-#else
-  #define JOY_X A6
-  #define JOY_Y A7
-  #define JOY_BTN 4
-#endif
-
-//analog joystick parameters
-// uint8_t pin,
-// uint8_t sensivity=5,
-// bool inv=false,
-// int center=512,
-// int inertia=6,
-// int bufferSz=1,
-// navCmds posCmd=upCmd,
-// navCmds negCmd=downCmd
-analogAxis<JOY_Y,10,false> ay;
-
-int test=500;
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  ,FIELD(test,"Test","ms",0,1000,100,1,doNothing,noEvent,wrapStyle)
-  ,EXIT("<Back")
-);
-
-//joystick button pin
-#define joyBtn 4
-
-keyMap btnsMap[]={{-joyBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-keyIn<1> btns(btnsMap);// 1 is the number of keys
-
-serialIn menuSerialIn(Serial);
-
-MENU_INPUTS(in,&ay,&btns,&menuSerialIn);
-
-#define MAX_DEPTH 1
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  btns.begin();
-  Serial.println("Menu 4.x joysick example");
-}
-
-void loop() {
-  nav.poll();
-  // while(menuSerialIn.available())
-  //   Serial.write(menuSerialIn.read());
-  delay(100);
-}
diff --git a/examples/atmega/.vscode/c_cpp_properties.json b/examples/atmega/.vscode/c_cpp_properties.json
new file mode 100644
index 00000000..be4ee3b4
--- /dev/null
+++ b/examples/atmega/.vscode/c_cpp_properties.json
@@ -0,0 +1,72 @@
+//
+// !!! WARNING !!! AUTO-GENERATED FILE!
+// PLEASE DO NOT MODIFY IT AND USE "platformio.ini":
+// https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
+//
+{
+    "configurations": [
+        {
+            "name": "PlatformIO",
+            "includePath": [
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/atmega/include",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/atmega/src",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/src",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/include",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/src",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/tinyTimeUtils/src",
+                "/home/azevedo/.platformio/packages/framework-arduino-avr/cores/arduino",
+                "/home/azevedo/.platformio/packages/framework-arduino-avr/variants/standard",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/.git",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples",
+                "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src",
+                "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/HID/src",
+                "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/SPI/src",
+                "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/SoftwareSerial/src",
+                "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/Wire/src",
+                "/home/azevedo/.platformio/packages/tool-unity",
+                ""
+            ],
+            "browse": {
+                "limitSymbolsToIncludedHeaders": true,
+                "path": [
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/atmega/include",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/atmega/src",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/src",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/include",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/src",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/tinyTimeUtils/src",
+                    "/home/azevedo/.platformio/packages/framework-arduino-avr/cores/arduino",
+                    "/home/azevedo/.platformio/packages/framework-arduino-avr/variants/standard",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/.git",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples",
+                    "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src",
+                    "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/HID/src",
+                    "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/SPI/src",
+                    "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/SoftwareSerial/src",
+                    "/home/azevedo/.platformio/packages/framework-arduino-avr/libraries/Wire/src",
+                    "/home/azevedo/.platformio/packages/tool-unity",
+                    ""
+                ]
+            },
+            "defines": [
+                "PLATFORMIO=50101",
+                "ARDUINO_AVR_UNO",
+                "NO_RELEASE",
+                "RS_DEBUG",
+                "F_CPU=16000000L",
+                "ARDUINO_ARCH_AVR",
+                "ARDUINO=10808",
+                "__AVR_ATmega328P__",
+                ""
+            ],
+            "cStandard": "c11",
+            "cppStandard": "c++11",
+            "compilerPath": "/home/azevedo/.platformio/packages/toolchain-atmelavr/bin/avr-gcc",
+            "compilerArgs": [
+                "-mmcu=atmega328p",
+                ""
+            ]
+        }
+    ],
+    "version": 4
+}
diff --git a/examples/atmega/.vscode/extensions.json b/examples/atmega/.vscode/extensions.json
new file mode 100644
index 00000000..0f0d7401
--- /dev/null
+++ b/examples/atmega/.vscode/extensions.json
@@ -0,0 +1,7 @@
+{
+    // See http://go.microsoft.com/fwlink/?LinkId=827846
+    // for the documentation about the extensions.json format
+    "recommendations": [
+        "platformio.platformio-ide"
+    ]
+}
diff --git a/examples/atmega/.vscode/launch.json b/examples/atmega/.vscode/launch.json
new file mode 100644
index 00000000..5135b6ae
--- /dev/null
+++ b/examples/atmega/.vscode/launch.json
@@ -0,0 +1,34 @@
+// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY
+//
+// PIO Unified Debugger
+//
+// Documentation: https://docs.platformio.org/page/plus/debugging.html
+// Configuration: https://docs.platformio.org/page/projectconf/section_env_debug.html
+
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "type": "platformio-debug",
+            "request": "launch",
+            "name": "PIO Debug",
+            "executable": "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/atmega/.pio/build/atmega/firmware.elf",
+            "projectEnvName": "atmega",
+            "toolchainBinDir": "/home/azevedo/.platformio/packages/toolchain-atmelavr/bin",
+            "internalConsoleOptions": "openOnSessionStart",
+            "preLaunchTask": {
+                "type": "PlatformIO",
+                "task": "Pre-Debug (atmega)"
+            }
+        },
+        {
+            "type": "platformio-debug",
+            "request": "launch",
+            "name": "PIO Debug (skip Pre-Debug)",
+            "executable": "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/atmega/.pio/build/atmega/firmware.elf",
+            "projectEnvName": "atmega",
+            "toolchainBinDir": "/home/azevedo/.platformio/packages/toolchain-atmelavr/bin",
+            "internalConsoleOptions": "openOnSessionStart"
+        }
+    ]
+}
diff --git a/examples/LCDs/LiquidCrystal/include/readme.txt b/examples/atmega/include/README
similarity index 100%
rename from examples/LCDs/LiquidCrystal/include/readme.txt
rename to examples/atmega/include/README
diff --git a/examples/atmega/lib/README b/examples/atmega/lib/README
new file mode 100644
index 00000000..6debab1e
--- /dev/null
+++ b/examples/atmega/lib/README
@@ -0,0 +1,46 @@
+
+This directory is intended for project specific (private) libraries.
+PlatformIO will compile them to static libraries and link into executable file.
+
+The source code of each library should be placed in a an own separate directory
+("lib/your_library_name/[here are source files]").
+
+For example, see a structure of the following two libraries `Foo` and `Bar`:
+
+|--lib
+|  |
+|  |--Bar
+|  |  |--docs
+|  |  |--examples
+|  |  |--src
+|  |     |- Bar.c
+|  |     |- Bar.h
+|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
+|  |
+|  |--Foo
+|  |  |- Foo.c
+|  |  |- Foo.h
+|  |
+|  |- README --> THIS FILE
+|
+|- platformio.ini
+|--src
+   |- main.c
+
+and a contents of `src/main.c`:
+```
+#include <Foo.h>
+#include <Bar.h>
+
+int main (void)
+{
+  ...
+}
+
+```
+
+PlatformIO Library Dependency Finder will find automatically dependent
+libraries scanning project source files.
+
+More information about PlatformIO Library Dependency Finder
+- https://docs.platformio.org/page/librarymanager/ldf.html
diff --git a/examples/atmega/platformio.ini b/examples/atmega/platformio.ini
new file mode 100644
index 00000000..9f6453d8
--- /dev/null
+++ b/examples/atmega/platformio.ini
@@ -0,0 +1,43 @@
+; PlatformIO Project Configuration File
+;
+;   Build options: build flags, source filter
+;   Upload options: custom upload port, speed and extra flags
+;   Library options: dependencies, extra library storages
+;   Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[platformio]
+default_envs = atmega
+
+[env:tiny]
+board = attiny45
+platform = atmelavr
+framework = arduino
+upload_protocol = usbasp
+upload_flags = -Pusb
+board_build.f_cpu = 8000000L
+monitor_speed = 115200
+board_fuses.lfuse = 0xD2
+board_fuses.hfuse = 0xDF
+build_flags = 
+	-DNO_RELEASE
+	-DAQUA_REMOTE_0
+	-DNO_RS_DEBUG
+lib_extra_dirs = 
+	~/Work/r-site.net/AM5/ArduinoMenu
+
+[env:atmega]
+board = uno
+platform = atmelavr
+framework = arduino
+monitor_speed = 115200
+monitor_port = /dev/ttyUSB1
+upload_port = /dev/ttyUSB1
+build_flags = 
+	-DNO_RELEASE
+	-DRS_DEBUG
+	-Wno-sign-compare
+lib_extra_dirs = 
+	~/Work/r-site.net/AM5/ArduinoMenu
diff --git a/examples/atmega/src/atmega.ino b/examples/atmega/src/atmega.ino
new file mode 100644
index 00000000..8876cca4
--- /dev/null
+++ b/examples/atmega/src/atmega.ino
@@ -0,0 +1,244 @@
+#include <Arduino.h>
+#include <menu.h>
+#include <menu/IO/pcArrows.h>
+#include <menu/IO/AM4Keys.h>
+#include <menu/IO/Arduino/serialIO.h>
+#include <menu/in.h>
+#include <menu/nav.h>
+#include <menu/framework/arduino.h>
+
+using namespace Menu;
+
+// template<typename O=Nil> 
+// struct ArduinoFramework:O {
+//   inline static uint32_t ms() {return millis();}
+//   inline static uint32_t us() {return micros();}
+// };
+
+struct Config {
+  template<typename O=Nil>
+  struct Part:TinyPlatform<O> {
+    using Idx=word;
+  };
+};
+
+using Cfg=Config::Part<ArduinoFramework<>>;
+CONFIG_MENU_LIB(Cfg)
+
+using Out=OutDef<
+  // OnFmt<Fmt::Title,PrintWrap<>::Part>::Part,
+  // RangePanel<5>::Part,
+  TitlePrinter::Part,
+  BodyPrinter::Part,
+  BasePrinter::Part,
+  TextEditMode::Part,
+  TextFmt::Part,//format translation
+  // FullPrinter::Part,//format emit
+  // XmlFmt::Part,
+  // StdOut::Part//raw output device
+  SerialOut<decltype(Serial),Serial>::Part
+>; Out out;
+
+bool menu_action() {
+  Serial.println("menu action called");
+  return false;
+}
+
+bool submenu_action() {
+  Serial.println("sub-menu action called");
+  return true;
+}
+
+bool op1_action() {
+  Serial.println("op 1 action.");
+  return false;
+}
+
+bool op2_action() {
+  Serial.println("op 2 action.");
+  return false;
+}
+
+bool sub1_action() {
+  Serial.println("sub 1 action.");
+  return true;
+}
+
+bool sub2_action() {
+  Serial.println("sub 2 action.");
+  return false;
+}
+
+bool imain_action() {
+  Serial.println("iMainMenu action.");
+  return true;
+}
+
+bool tog12_action();
+
+bool running=true;
+int perc=50;
+bool quit() {return running=false;}
+
+ConstText quit_text="<Quit!";
+using Quit=ItemDef<Action<quit>::Part,StaticText<&quit_text>::Part>;
+using IQuit=ItemDef<Prompt::Part,Action<quit>::Part,StaticText<&quit_text>::Part>;
+
+ConstText exit_text="<Exit";
+using Exit=ItemDef<StaticText<&exit_text>::Part>;
+using IExit=ItemDef<Prompt::Part,StaticText<&exit_text>::Part>;
+
+ConstText title_text="Main menu";
+ConstText op2_text="op2";
+ConstText tog12_text="Toggle En/Dis";
+ConstText opn_text="...";
+ConstText celsius="℃ ";
+ConstText addr_label="Address";
+
+ConstText op1_text="op1";
+ConstText temp_text="Temp.";
+ConstText subMenu_title_text="Sub-menu";
+ConstText sub1_text="Sub op 1";
+ConstText sub2_text="Sub op 2";
+
+ConstText trig_text="Trigger";
+ConstText trig0_text="None";
+ConstText trig1_text="Rise";
+ConstText trig2_text="Fall";
+ConstText trig3_text="Both";
+enum class Trig {None,Rise,Fall,Both};
+// template<typename O>
+// O& operator<<(O& out,Trig t) {
+//   switch(t) {
+//     case Trig::None:return out<<"None";
+//     case Trig::Rise:return out<<"Rise";
+//     case Trig::Fall:return out<<"Fall";
+//     case Trig::Both:return out<<"Both";
+//     default: return out;
+//   }
+// }
+Trig trig=Trig::None;
+
+char addr_buffer[]="000";//buffer to be edited
+const char* addr_mask[]={"0123456789ABCDEF"};//edit mask for previous buffer
+const char* ox="0x";//hex prefix
+
+using TrigOptions=StaticMenuBody<
+  ItemDef<StaticText<&trig0_text>::Part,Value<Trig,Trig::None>::Part>
+  ,ItemDef<StaticText<&trig1_text>::Part,Value<Trig,Trig::Rise>::Part>
+  ,ItemDef<StaticText<&trig2_text>::Part,Value<Trig,Trig::Fall>::Part>
+  ,ItemDef<StaticText<&trig3_text>::Part,Value<Trig,Trig::Both>::Part>
+>;
+
+using MainMenu=StaticMenu<
+  ItemDef<StaticText<&title_text>::Part>
+  ,WrapNav::Part<//this menu will wrap
+    StaticMenuBody<
+      ItemDef<EnDis<true>::Part,Action<op1_action>::Part,StaticText<&op1_text>::Part>
+      ,ItemDef<EnDis<false>::Part,Action<op2_action>::Part,StaticText<&op2_text>::Part>
+      ,ItemDef<Action<tog12_action>::Part,StaticText<&tog12_text>::Part>
+      ,ItemDef<
+        StaticLabel<&addr_label>::Part,
+        AsEditMode::Part,
+        StaticText<&ox>::Part,//some special text between the cursor and the data
+        AsValue::Part,
+        TextEditBase<addr_buffer,sizeof(addr_buffer)/sizeof(addr_label[0]),addr_mask>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&trig_text>::Part
+        ,AsValue::Part 
+        ,Toggle<
+          StaticMenu<
+            ItemDef<StaticLabel<&trig_text>::Part>::Part
+            ,WrapNav::Part<TrigOptions>
+          >
+        >::Part
+        ,FieldRef<Trig,trig,Trig::None>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&trig_text>::Part
+        ,AsEditMode::Part
+        ,AsValue::Part
+        ,Select<
+          StaticMenu<
+            ItemDef<StaticLabel<&trig_text>::Part>::Part
+            ,WrapNav::Part<TrigOptions>
+          >
+        >::Part
+        ,FieldRef<Trig,trig,Trig::None>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&trig_text>::Part
+        ,AsEditMode::Part
+        ,AsValue::Part 
+        ,Choose<
+          StaticMenu<
+            ItemDef<StaticLabel<&trig_text>::Part>
+            ,TrigOptions
+          >
+        >::Part
+        ,FieldRef<Trig,trig,Trig::None>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&temp_text>::Part
+        ,AsEditMode::Part
+        ,AsValue::Part
+        ,Chain<
+          NumRef<decltype(perc),perc>::Part,
+          StaticSTRange<decltype(perc),0,100,10,1>::Part
+        >::Part
+        ,AsUnit::Part
+        ,StaticText<&celsius>::Part
+      >
+      ,Action<submenu_action>::Part<
+        StaticMenu<
+          ItemDef<StaticText<&subMenu_title_text>::Part>
+          ,StaticMenuBody<
+            ItemDef<Action<sub1_action>::Part,StaticText<&sub1_text>::Part>
+            ,ItemDef<Action<sub2_action>::Part,StaticText<&sub2_text>::Part>
+            ,ItemDef<StaticText<&opn_text>::Part>
+            ,ItemDef<StaticText<&opn_text>::Part>
+            ,Exit
+          >
+        >
+      >
+      ,ItemDef<StaticText<&opn_text>::Part>
+      // ,Quit
+    >
+  >
+>;
+
+MainMenu mainMenu;
+
+// togle enable/disable on first 2 options
+bool tog12_action() {
+  // _trace(mdo<<"toggling 1&2\n\r");
+  bool en1=Path<0>().walk<MainMenu,Enabled>(mainMenu);
+  bool en2=Path<1>().walk<MainMenu,Enabled>(mainMenu);
+  Path<0>().walk<MainMenu,Enable,bool>(mainMenu,!en1);
+  Path<1>().walk<MainMenu,Enable,bool>(mainMenu,!en2);
+  return true;
+}
+
+//navigation API
+using Nav=NavDef<StaticNav<MainMenu,4>::Part>;
+Nav nav(mainMenu);
+
+// NavDef<StaticNav<IMainMenu,3>::Part> iNav(iMainMenu);
+//menu input --------------------------------------
+InDef<
+  ArduinoSerialIn<>::Part,
+  AM4Parser::Part,//use AM4 navigation keys `+-*/`
+  PCArrows::Part//using PC keys
+> in;
+
+void setup() {
+  Serial.begin(115200);
+  while(!Serial);
+}
+
+void loop() {
+  if(nav.doInput(in)) nav.printTo(out);
+  // in.relax();//use poll instead...
+  // nav.relax();//TODO: only when idling (reset otherwise)
+}
\ No newline at end of file
diff --git a/examples/atmega/test/README b/examples/atmega/test/README
new file mode 100644
index 00000000..b94d0890
--- /dev/null
+++ b/examples/atmega/test/README
@@ -0,0 +1,11 @@
+
+This directory is intended for PlatformIO Unit Testing and project tests.
+
+Unit Testing is a software testing method by which individual units of
+source code, sets of one or more MCU program modules together with associated
+control data, usage procedures, and operating procedures, are tested to
+determine whether they are fit for use. Unit testing finds problems early
+in the development cycle.
+
+More information about PlatformIO Unit Testing:
+- https://docs.platformio.org/page/plus/unit-testing.html
diff --git a/examples/btnNav/btnNav/btnNav.ino b/examples/btnNav/btnNav/btnNav.ino
deleted file mode 100644
index 70d5653c..00000000
--- a/examples/btnNav/btnNav/btnNav.ino
+++ /dev/null
@@ -1,156 +0,0 @@
-/* Arduino menu library example
-Oct. 2016 Rui Azevedo (ruihfazevedo@gmail.com) www.r-site.net
-
-Digital keypad (3 buttons) using the menu keyIn driver
-*/
-
-#include <Arduino.h>
-#include <menu.h>
-#include <menuIO/serialIn.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/altKeyIn.h>
-#include <menuIO/chainStream.h>
-
-using namespace Menu;
-
-#define LEDPIN 13
-#define MAX_DEPTH 2
-
-#define BTN_SEL 6	// Select button
-#define BTN_UP 7 // Up
-#define BTN_DOWN 8 // Down
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action1 event:");
-  Serial.println(e);
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e) {
-  Serial.print("actikon2 event:");
-  Serial.println(e);
-  Serial.flush();
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,wrapStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,wrapStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,wrapStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",doNothing,anyEvent,wrapStyle
-  ,OP("Sub1",showEvent,enterEvent)
-  ,OP("Sub2",showEvent,enterEvent)
-  ,OP("Sub3",showEvent,enterEvent)
-  ,altOP(altPrompt,"",showEvent,enterEvent)
-  ,EXIT("<Back")
-);
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  //,SUBMENU(togOp)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EXIT("<Back")
-);
-
-keyMap joystickBtn_map[]={
- {-BTN_SEL, defaultNavCodes[enterCmd].ch,INPUT_PULLUP} ,
- {-BTN_UP, defaultNavCodes[upCmd].ch,INPUT_PULLUP} ,
- {-BTN_DOWN, defaultNavCodes[downCmd].ch,INPUT_PULLUP}  ,
-};
-keyIn<3> joystickBtns(joystickBtn_map);
-
-serialIn serial(Serial);
-menuIn* inputsList[]={&joystickBtns,&serial};
-chainStream<2> in(inputsList);//3 is the number of inputs
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("[select] to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  pinMode(LEDPIN, OUTPUT);
-  joystickBtns.begin();
-}
-
-#define SOFT_DEBOUNCE_MS 100
-
-void loop() {
-  nav.poll();//also do serial input
-  digitalWrite(LEDPIN, ledCtrl);
-}
diff --git a/examples/clickEncoder/clickEncoder/clickEncoder.ino b/examples/clickEncoder/clickEncoder/clickEncoder.ino
deleted file mode 100644
index 04787106..00000000
--- a/examples/clickEncoder/clickEncoder/clickEncoder.ino
+++ /dev/null
@@ -1,208 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Arduino generic menu system
-Arduino menu using clickEncoder and I2C LCD
-
-Sep.2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Feb.2018 Ken-Fitz - https://github.com/Ken-Fitz
-
-LCD library:
-https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
-http://playground.arduino.cc/Code/LCD3wires
-*/
-
-#include <Wire.h>
-#include <LiquidCrystal_I2C.h>//F. Malpartida LCD's driver
-#include <menu.h>//menu macros and objects
-#include <menuIO/lcdOut.h>//malpartidas lcd menu output
-#include <TimerOne.h>
-#include <ClickEncoder.h>
-#include <menuIO/clickEncoderIn.h>
-#include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-using namespace Menu;
-
-//LiquidCrystal_I2C lcd(0x27);//, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
-LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3,POSITIVE);  // Set the LCD I2C address and pinout
-
-// Encoder /////////////////////////////////////
-#define encA 24
-#define encB 22
-//this encoder has a button here
-#define encBtn 26
-
-
-ClickEncoder clickEncoder(encA,encB,encBtn,2);
-ClickEncoderStream encStream(clickEncoder,1);
-MENU_INPUTS(in,&encStream);
-void timerIsr() {clickEncoder.service();}
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action1 event: ");
-  Serial.print(e);
-  Serial.println(", proceed menu");
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action2 event: ");
-  Serial.print(e);
-  Serial.println(", quiting menu.");
-  Serial.flush();
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-/*extern menu mainMenu;
-TOGGLE((mainMenu[1].enabled),togOp,"Op 2:",doNothing,noEvent,noStyle
-  ,VALUE("Enabled",enabledStatus,doNothing,noEvent)
-  ,VALUE("disabled",disabledStatus,doNothing,noEvent)
-);*/
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("OpA",action1,anyEvent)
-  ,OP("OpB",action2,enterEvent)
-  //,SUBMENU(togOp)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-/*constMEM panel panels[] MEMMODE={{0,0,16,2}};
-navNode* nodes[sizeof(panels)/sizeof(panel)];
-panelsList pList(panels,nodes,1);
-idx_t tops[MAX_DEPTH];
-lcdOut outLCD(&lcd,tops,pList);//output device for LCD
-menuOut* constMEM outputs[] MEMMODE={&outLCD};//list of output devices
-outputsList out(outputs,1);//outputs list with 2 outputs
-*/
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,LCD_OUT(lcd,{0,0,20,4})
-  ,NONE
-);
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);//the navigation root object
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("[select] to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-result idle(menuOut& o,idleEvent e) {
-  switch(e) {
-    case idleStart:o.print("suspending menu!");break;
-    case idling:o.print("suspended...");break;
-    case idleEnd:o.print("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(encBtn,INPUT_PULLUP);
-  pinMode(LED_BUILTIN,OUTPUT);
-  Serial.begin(9600);
-  while(!Serial);
-  Serial.println("Arduino Menu Library");Serial.flush();
-  lcd.begin(20,4);
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  mainMenu[1].enabled=disabledStatus;
-  nav.showTitle=false;
-  lcd.setCursor(0, 0);
-  lcd.print("Menu 4.x LCD");
-  lcd.setCursor(0, 1);
-  lcd.print("r-site.net");
-  Timer1.initialize(1000);
-  Timer1.attachInterrupt(timerIsr);
-  delay(2000);
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LED_BUILTIN, ledCtrl);
-  delay(100);//simulate a delay as if other tasks are running
-}
diff --git a/examples/codeCtrl/.gitignore b/examples/codeCtrl/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/codeCtrl/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/codeCtrl/.travis.yml b/examples/codeCtrl/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/codeCtrl/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/codeCtrl/codeCtrl/codeCtrl.ino b/examples/codeCtrl/codeCtrl/codeCtrl.ino
deleted file mode 100644
index f559f15a..00000000
--- a/examples/codeCtrl/codeCtrl/codeCtrl.ino
+++ /dev/null
@@ -1,193 +0,0 @@
-/* Arduino menu library example
-Oct. 2016 Rui Azevedo (ruihfazevedo@gmail.com) www.r-site.net
-
-Use the menu library with user code ctrl command
-
-calling doNav with user command mode:
-
-noCmd - clamp field values or do nothing
-escCmd - exit
-enterCmd - enter current option or validate field and exit
-upCmd - move up or increment field value
-downCmd - move down or decrement field value
-leftCmd - move left or escape (not tested yet)
-rightCmd - move right or enter (not tested yet)
-idxCmd - enter option by index
-
-this mode allows you to implement ANY input device
-
-on this example only using
-
-*/
-
-#include <Arduino.h>
-#include <menu.h>
-#include <menuIO/serialIO.h>
-#include <menuIO/stringIn.h>
-#include <menuIO/chainStream.h>
-
-using namespace Menu;
-
-#define LEDPIN 13
-#define MAX_DEPTH 2
-#define NAV_BTN 5
-#define SEL_BTN 6
-
-result doAlert(eventMask e, prompt &item);
-
-result showEvent(eventMask e) {
-  Serial.print("event: ");
-  Serial.println(e);
-  return proceed;
-}
-
-int test=55;
-
-result action1(eventMask e,navNode& nav, prompt &item) {
-  Serial.print("action1 event:");
-  Serial.println(e);
-  Serial.flush();
-  return proceed;
-}
-
-result action2(eventMask e) {
-  Serial.print("actikon2 event:");
-  Serial.println(e);
-  Serial.flush();
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,wrapStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,wrapStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,wrapStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",doNothing,anyEvent,wrapStyle
-  ,OP("Sub1",showEvent,enterEvent)
-  ,OP("Sub2",showEvent,enterEvent)
-  ,OP("Sub3",showEvent,enterEvent)
-  ,altOP(altPrompt,"",showEvent,enterEvent)
-  ,EXIT("<Back")
-);
-
-constText* constMEM textFilter MEMMODE=" .0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTWXYZ";
-constText* constMEM textMask[] MEMMODE={textFilter};//this mask will repeat till the end of the field
-char name[]="          ";//<-- menu will edit this text
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  ,EDIT("Name",name,textMask,doNothing,noEvent,noStyle)
-  //,SUBMENU(togOp)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EXIT("<Back")
-);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-stringIn<0> strIn;//buffer size: 2^5 = 32 bytes, eventually use 0 for a single byte
-serialIn serial(Serial);
-// use this commented lines if you want your stringIn object to be used as part or normal menu input
-// menuIn* inputsList[]={&serial,&strIn};
-// chainStream<sizeof(inputsList)> in(inputsList);
-// NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("[select] to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  pinMode(LEDPIN, OUTPUT);
-  pinMode(NAV_BTN,INPUT_PULLUP);
-  pinMode(SEL_BTN,INPUT_PULLUP);
-  Serial.println("menu 4.x");
-}
-
-#define SOFT_DEBOUNCE_MS 100
-
-void loop() {
-  if (!digitalRead(SEL_BTN)) {
-    delay(SOFT_DEBOUNCE_MS);
-    while(!digitalRead(SEL_BTN));
-    nav.doNav(enterCmd);
-    delay(SOFT_DEBOUNCE_MS);
-  }
-  if (!digitalRead(NAV_BTN)) {
-    delay(SOFT_DEBOUNCE_MS);
-    while(!digitalRead(NAV_BTN));//wait for button release
-    nav.doNav(upCmd);
-    delay(SOFT_DEBOUNCE_MS);
-  }
-  //if stringIn is a regular input then we should write to it here, before poll
-  // strIn.write(...);//just put the character you want to send
-  // nav.poll();//also do serial or stringIn input
-  // or deal with charater input directly... (if you have your own input driver)
-  if (Serial.available()) {
-    //of course menu can read from Serial or even stringIn (se above how to use stringIn as a regular menu input)
-    //but here we demonstrate the use of stringIn in direct call, by writing the data to stream and then call doInput with that stream
-    if (strIn.write(Serial.read()))//so we just transfer data from serial to strIn
-      nav.doInput(strIn);//and then let target parse input
-  }
-  nav.doOutput();//if not doing poll the we need to do output "manualy"
-  digitalWrite(LEDPIN, ledCtrl);
-}
diff --git a/examples/codeCtrl/platformio.ini b/examples/codeCtrl/platformio.ini
deleted file mode 100644
index c1cdeb9b..00000000
--- a/examples/codeCtrl/platformio.ini
+++ /dev/null
@@ -1,37 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=codeCtrl
-; lib_dir=~/Arduino/Libraries
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -Wno-switch
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -DDEBUG
-
-; [env:uno]
-; platform = atmelavr
-; board = nanoatmega328
-; framework = arduino
-;
-; [env:esp01_1m]
-; platform=espressif8266
-; board=esp01_1m
-; framework=arduino
diff --git a/examples/concurrent/concurrent/concurrent.ino b/examples/concurrent/concurrent/concurrent.ino
deleted file mode 100644
index a803e1fc..00000000
--- a/examples/concurrent/concurrent/concurrent.ino
+++ /dev/null
@@ -1,99 +0,0 @@
-/********************
-Sept. 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-Concurrent menu test
-output: I2C LCD (Malpartida) and Serial
-input: encoder + Serial
-purpose: test independent concurrent menus on two different devices
-  the same menu could also be used to independent navigation on two output devices
-www.r-site.net
-
-***/
-
-#include <Arduino.h>
-
-#include <Wire.h>
-#include <LiquidCrystal_I2C.h>//F. Malpartida LCD's driver
-#include <menu.h>//menu macros and objects
-#include <menuIO/lcdOut.h>//malpartidas lcd menu output
-#include <menuIO/encoderIn.h>//quadrature encoder driver and fake stream
-#include <menuIO/keyIn.h>//keyboard driver and fake stream (for the encoder button)
-#include <menuIO/chainStream.h>// concatenate multiple input streams (this allows adding a button to the encoder)
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address and pinout
-
-// Encoder /////////////////////////////////////
-#define encA 2
-#define encB 3
-//this encoder has a button here
-#define encBtn 4
-
-encoderIn<encA,encB> encoder;//simple quad encoder driver
-#define ENC_SENSIVITY 4
-encoderInStream<encA,encB> encStream(encoder,ENC_SENSIVITY);// simple quad encoder fake Stream
-
-//a keyboard with only one key as the encoder button
-keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-keyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-//input from the encoder + encoder button + serial
-menuIn* inputsList[]={&encStream,&encButton};
-chainStream<2> in(inputsList);//2 is the number of inputs
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-#define MAIN_MAX_DEPTH 1
-
-MENU_OUTPUTS(mainout,MAIN_MAX_DEPTH
-  ,LCD_OUT(lcd,{0,0,16,2})
-  ,NONE
-);
-
-NAVROOT(mainNav,mainMenu,MAIN_MAX_DEPTH,in,mainout);//the navigation root object
-
-//--- define a second (aux) menu with independent IO --------------------------
-MENU(auxMenu,"Aux menu",doNothing,noEvent,wrapStyle
-  ,OP("Aux1",doNothing,noEvent)
-  ,OP("Aux2",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-#define AUX_MAX_DEPTH 1
-
-MENU_OUTPUTS(auxOut,AUX_MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE
-);
-
-serialIn serial(Serial);
-NAVROOT(auxNav,auxMenu,AUX_MAX_DEPTH,serial,auxOut);//the navigation root object
-//---------------------------
-
-void setup() {
-  pinMode(encBtn,INPUT_PULLUP);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Arduino Menu Library 4.x concurrent test");Serial.flush();
-  encoder.begin();
-  lcd.begin(16,2);
-  mainNav.showTitle=false;
-  lcd.setCursor(0, 0);
-  lcd.print("Menu 4.x LCD");
-  lcd.setCursor(0, 1);
-  lcd.print("r-site.net");
-  delay(2000);
-}
-
-void loop() {
-  mainNav.poll();
-  auxNav.poll();
-  delay(100);//simulate a delay as if other tasks are running
-}
diff --git a/examples/console/.vscode/c_cpp_properties.json b/examples/console/.vscode/c_cpp_properties.json
new file mode 100644
index 00000000..f130fe4e
--- /dev/null
+++ b/examples/console/.vscode/c_cpp_properties.json
@@ -0,0 +1,49 @@
+//
+// !!! WARNING !!! AUTO-GENERATED FILE!
+// PLEASE DO NOT MODIFY IT AND USE "platformio.ini":
+// https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
+//
+{
+    "configurations": [
+        {
+            "name": "PlatformIO",
+            "includePath": [
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/console/include",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/console/src",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/src",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/include",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/src",
+                "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/.git",
+                "/home/azevedo/.platformio/packages/tool-unity",
+                ""
+            ],
+            "browse": {
+                "limitSymbolsToIncludedHeaders": true,
+                "path": [
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/console/include",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples/console/src",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/examples",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/src",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/include",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/parts/src",
+                    "/home/azevedo/Work/r-site.net/AM5/ArduinoMenu/.git",
+                    "/home/azevedo/.platformio/packages/tool-unity",
+                    ""
+                ]
+            },
+            "defines": [
+                "PLATFORMIO=50101",
+                "NO_RS_DEBUG",
+                "DEFAULT_LANG=lang_pt",
+                ""
+            ],
+            "cppStandard": "c++11",
+            "compilerPath": "/usr/bin/gcc",
+            "compilerArgs": [
+                ""
+            ]
+        }
+    ],
+    "version": 4
+}
diff --git a/examples/console/.vscode/extensions.json b/examples/console/.vscode/extensions.json
new file mode 100644
index 00000000..0f0d7401
--- /dev/null
+++ b/examples/console/.vscode/extensions.json
@@ -0,0 +1,7 @@
+{
+    // See http://go.microsoft.com/fwlink/?LinkId=827846
+    // for the documentation about the extensions.json format
+    "recommendations": [
+        "platformio.platformio-ide"
+    ]
+}
diff --git a/examples/console/.vscode/launch.json b/examples/console/.vscode/launch.json
new file mode 100644
index 00000000..e6e1ff10
--- /dev/null
+++ b/examples/console/.vscode/launch.json
@@ -0,0 +1,53 @@
+// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY
+//
+// PIO Unified Debugger
+//
+// Documentation: https://docs.platformio.org/page/plus/debugging.html
+// Configuration: https://docs.platformio.org/page/projectconf/section_env_debug.html
+
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "(gdb) Launch",
+            "type": "cppdbg",
+            "request": "launch",
+            "program": "${workspaceFolder}/.pio/build/native/program",
+            "args": [],
+            "stopAtEntry": false,
+            "cwd": "${workspaceFolder}",
+            "environment": [],
+            "externalConsole": false,
+            "MIMode": "gdb",
+            "setupCommands": [
+                {
+                    "description": "Enable pretty-printing for gdb",
+                    "text": "-enable-pretty-printing",
+                    "ignoreFailures": true
+                }
+            ]
+        },
+        {
+            "type": "platformio-debug",
+            "request": "launch",
+            "name": "PIO Debug",
+            "executable": "${workspaceFolder}/.pio/build/native/program",
+            "projectEnvName": "native",
+            "toolchainBinDir": "",
+            "internalConsoleOptions": "openOnSessionStart",
+            "preLaunchTask": {
+                "type": "PlatformIO",
+                "task": "Pre-Debug"
+            }
+        },
+        {
+            "type": "platformio-debug",
+            "request": "launch",
+            "name": "PIO Debug (skip Pre-Debug)",
+            "executable": "${workspaceFolder}/.pio/build/native/program",
+            "projectEnvName": "native",
+            "toolchainBinDir": "",
+            "internalConsoleOptions": "openOnSessionStart"
+        }
+    ]
+}
\ No newline at end of file
diff --git a/examples/console/.vscode/tasks.json b/examples/console/.vscode/tasks.json
new file mode 100644
index 00000000..afc57a45
--- /dev/null
+++ b/examples/console/.vscode/tasks.json
@@ -0,0 +1,31 @@
+{
+	"version": "2.0.0",
+	"tasks": [
+		{
+			"type": "cppbuild",
+			"label": "C/C++: build src/main.cpp",
+			"command": "/usr/bin/g++",
+			"args": [
+				"-g",
+				"${workspaceFolder}/src/main.cpp",
+				"-o",
+				"${workspaceFolder}/.pio/build/native/program",
+				"-fdiagnostics-color=always",
+				"-I${workspaceFolder}/../../src",
+				"-DRS_DEBUG",
+				"-DDEFAULT_LANG=lang_en"
+			],
+			"options": {
+				"cwd": "${workspaceFolder}"
+			},
+			"problemMatcher": [
+				"$gcc"
+			],
+			"group": {
+				"kind": "build",
+				"isDefault": true
+			},
+			"detail": "compiler: /usr/bin/g++"
+		}
+	]
+}
\ No newline at end of file
diff --git a/examples/LCDs/Malpartida/I2C/include/readme.txt b/examples/console/include/README
similarity index 100%
rename from examples/LCDs/Malpartida/I2C/include/readme.txt
rename to examples/console/include/README
diff --git a/examples/console/lib/README b/examples/console/lib/README
new file mode 100644
index 00000000..6debab1e
--- /dev/null
+++ b/examples/console/lib/README
@@ -0,0 +1,46 @@
+
+This directory is intended for project specific (private) libraries.
+PlatformIO will compile them to static libraries and link into executable file.
+
+The source code of each library should be placed in a an own separate directory
+("lib/your_library_name/[here are source files]").
+
+For example, see a structure of the following two libraries `Foo` and `Bar`:
+
+|--lib
+|  |
+|  |--Bar
+|  |  |--docs
+|  |  |--examples
+|  |  |--src
+|  |     |- Bar.c
+|  |     |- Bar.h
+|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
+|  |
+|  |--Foo
+|  |  |- Foo.c
+|  |  |- Foo.h
+|  |
+|  |- README --> THIS FILE
+|
+|- platformio.ini
+|--src
+   |- main.c
+
+and a contents of `src/main.c`:
+```
+#include <Foo.h>
+#include <Bar.h>
+
+int main (void)
+{
+  ...
+}
+
+```
+
+PlatformIO Library Dependency Finder will find automatically dependent
+libraries scanning project source files.
+
+More information about PlatformIO Library Dependency Finder
+- https://docs.platformio.org/page/librarymanager/ldf.html
diff --git a/examples/console/platformio.ini b/examples/console/platformio.ini
new file mode 100644
index 00000000..896a0c77
--- /dev/null
+++ b/examples/console/platformio.ini
@@ -0,0 +1,23 @@
+
+; [env:uno]
+; monitor_speed = 115200
+; platform = atmelavr
+; board = uno
+; framework = arduino
+
+[env:native]
+monitor_speed = 115200
+platform = native
+lib_extra_dirs = ../../
+upload_protocol = custom
+upload_command= .pio/build/native/program
+build_flags =
+	-DNO_RS_DEBUG
+	-DDEFAULT_LANG=lang_pt
+	-ftemplate-depth=9000
+	-std=c++11
+	; -std=c++14
+	; -std=c++17
+	; -std=c++20
+	; -std=gnu++1z
+	-ggdb
diff --git a/examples/console/src/lang.cpp b/examples/console/src/lang.cpp
new file mode 100644
index 00000000..7dab7724
--- /dev/null
+++ b/examples/console/src/lang.cpp
@@ -0,0 +1,8 @@
+#include "lang.h"
+
+const char** langs[nLangs] {
+  lang_de::lang,
+  lang_en::lang,
+  lang_pt::lang
+};
+
diff --git a/examples/console/src/lang.h b/examples/console/src/lang.h
new file mode 100644
index 00000000..dfc718c6
--- /dev/null
+++ b/examples/console/src/lang.h
@@ -0,0 +1,124 @@
+/* -*- C++ -*- */
+#pragma once
+// LANGUAGE /////////////////////////////////////////////////////////
+// or define DEFAULT_LANG at compiler options (preferable)
+// #define DEFAULT_LANG lang_en
+// #define DEFAULT_LANG lang_pt
+// #define DEFAULT_LANG lang_de
+#ifndef DEFAULT_LANG
+  #error Must define DEFAULT_LANG, see lang.h file
+#endif
+
+enum Langs {de=0,en,pt,nLangs};
+//if having names on its own language this settings stay here (font problem, cant find a font to support all languages special chars)
+//if having language names in selected language this setting must replicate to lang/*.cpp files
+constexpr const char*langNames[nLangs]{"DE","EN","PT"};
+constexpr const char*langCodes[nLangs]{"de","en","pt"};
+
+enum TextId {
+  txtMain=0,
+  txtExit,
+  txtBack,
+  txtTime,
+  txtOn,
+  txtOff,
+  txtYes,
+  txtNo,
+  txtLevel,
+  txtSched,
+  txtSave,
+  txtLoad,
+  txtLed,
+  txtLight,
+  txtSettings,
+  txtStandby,
+  txtWifi,
+  txtWifiTog,
+  txtCloud,
+  txtThunder,
+  txtMoon,
+  txtDateTime,
+  txtOk,
+  txtCancel,
+  txtNoPack,
+  txtSeconds1900,
+  txtUseNTP,
+  txtGMT,
+  txtAddEntry,
+  txtAutoSched,
+  txtSlot,
+  txtAuto,
+  txtManual,
+  txtControl,
+  txtManualLevel,
+  txtPressSelect,
+  txtToCont,
+  txtNoWifi,
+  txtWifiError,
+  txtScan,
+  txtNoNet,
+  txtSelect,
+  txtSSID,
+  txtPwd,
+  txtConnect,
+  txtDisconnect,
+  txtMoonChan1,
+  txtMoonChan2,
+  txtMoonChan3,
+  txtMoonChan4,
+  txtMoonChan5,
+  txtMoonChan6,
+  txtSavedOk,
+  txtSaveError,
+  txtLoadedOk,
+  txtLoadError,
+  txtConWifi,
+  txtApPwd,
+  txtIP,
+  txtAccessPoint,
+  txtBackup,
+  txtRestore,
+  txtCloudMax,
+  txtThunderMax,
+  txtMoonMax,
+  txtDemo,
+  txtNTPsync,
+  txtDLS,
+  txtNTPset,
+  txtLang,
+  txtUpdate,
+  txtReset,
+  txtLCFactory,
+  txtAbout,
+  txtAboutText,
+  txtFactoryReset,
+  txtFactoryResetConfirm,
+  txtFactoryResetIgnore,
+  txtTimeOffset,
+  txtSetDateTime,
+  //------------------
+  nText//this one MUST be the last
+};
+
+namespace lang_de {
+  constexpr Langs fwLang=Langs::de;
+  extern const char* lang[nText];
+};
+namespace lang_en {
+  constexpr Langs fwLang=Langs::en;
+  extern const char* lang[nText];
+};
+namespace lang_pt {
+  constexpr Langs fwLang=Langs::pt;
+  extern const char* lang[nText];
+};
+
+// namespace lang_ru {
+//   constexpr Langs fwLang=Langs::ru;
+//   extern const char* lang[nText];
+// };
+
+using namespace DEFAULT_LANG;
+
+extern const char** langs[nLangs];
+
diff --git a/examples/console/src/lang/de.cpp b/examples/console/src/lang/de.cpp
new file mode 100644
index 00000000..870f01d4
--- /dev/null
+++ b/examples/console/src/lang/de.cpp
@@ -0,0 +1,103 @@
+/* -*- C++ -*- */
+
+#include "../lang.h"
+namespace lang_de {
+  const char* lang[(int)TextId::nText]{
+    #ifdef HEADLESS
+      "MicroTC361",//  txtMain,
+    #else
+      "MicroTC360",//  txtMain,
+    #endif
+    "Exit",//txtExit
+    "Zurück",
+    // "<Zur\xFcck",//txtBack,
+    "Zeit",//  txtTime,
+    "An",// txtOn,
+    "Aus",// txtOff,
+    "Ja",// txtYes,
+    "Nein",// txtNo,
+    "",//  txtLevel,
+    "",//  txtSched,
+    "Speichern",//  txtSave,
+    "Laden",//txtLoad
+    "Led",//  txtLed,
+    "Licht",//  txtLight,
+    "Einstellungen",//txtSettings,
+    "Standby",//txtStandby,
+    "Wi-Fi",//txtWifi,
+    "Wi-Fi:",//txtWifiTog,
+    "Wolken:",//txtCloud,
+    "Gewitter:",//txtThunder,
+    "Mondlicht",//txtMoon,
+    "Zeit/Datum einstellen",//txtDateTime,
+    "Ok",//txtOk
+    "Abbrechen",//txtCancel
+    "kein Packet empfangen",//txtNoPack
+    "Sekunden seit 1900",//txtSeconds1900
+    "benutze NTP",//txtUseNTP
+    "Zeitzone GMT",//txtGMT
+    "(+neuer Eintrag)",//txtAddEntry
+    "Auto. Verlauf",//txtAutoSched
+    "Slot",//txtSlot
+    "Auto",//txtAuto
+    "Manuell",//txtManual
+    "Control:",//txtControl
+    "Manuelles Level",//txtManualLevel
+    "drücke [select]",//txtPressSelect
+    "zum fortfahren...",//txtToCont
+    "kein WiFi gefunden",//txtNoWifi
+    "Wifi Fehler",//txtWifiError
+    "Suche...",//txtScan
+    "kein Netzwerk gefunden",//txtNoNet
+    "auswählen...",//txtSelect
+    "SSID:",//txtSSID
+    "Pwd",//txtPwd
+    "Verbinden",//txtConnect
+    "Trennen",//txtDisconnect
+    "#1",//txtMoonChan1
+    "#2",//txtMoonChan2
+    "#3",//txtMoonChan3
+    "#4",//txtMoonChan4
+    "#5",//txtMoonChan5
+    "#6",//txtMoonChan6
+    "gespeichert.",//txtSavedOk
+    "Speicher Fehler!",//txtSaveError
+    "geladen",//txtLoadedOk
+    "Lade Fehler!",//txtLoadError,
+    "Verbinde mit:",//txtConWifi
+    "Pwd: ",//txtApPwd
+    "IP: ",//txtIP
+    "Access Point",//txtAccessPoint
+    "Sichern",//txtBackup
+    "Laden",//txtRestore
+    "max",//txtCloudMax,
+    "max",//txtThunderMax,
+    "max",//txtMoonMax,
+    "Demo:",//txtDemo
+    "Datum / Uhrzeit erhalten...", //txtNTPsync
+    "Sommerzeit:",//txtDLS,
+    "Datum / Uhrzeit eingestellt",//txtNTPset
+    "Sprache",//txtLang
+    "Aktualisieren...",//txtUpdate
+    "Wiederherstellen!",//txtReset
+    "Verwenden der Werkseinstellungen",//txtLCFactory
+    #ifdef HEADLESS
+      "Über MicroTC361",//txtAbout
+    #else
+      "Über MicroTC360",//txtAbout
+    #endif
+    "Credits:\n\n"
+    "An dieser Stelle \nmöchten wir uns \nbei allen \nbedanken die \ndieses Projekt \nmöglich gemacht \nhaben:\n\n"
+    "Rui Azevedo von \nr-site.net / \nArduinoMenu für \nseine Hilfe beim \nProgrammieren \ndes MicroTC360/1 \nControllers, \ntesten und \ndebuggen\n\n"
+    "Tobias Gawrisch \nvon AquaOwner \nfür seine Ideen \nrund um die \nUNIQ FS LED \nSerie und die \nHilfe beim \nDesign\n\n"
+    "Oliver L. von \nOcean Optics \nder/die mich \nseit vielen \nJahren bei der \nForschung rund \num das Thema LED \nunterstützen\n\n"
+    "Kable, Sales \nManager der \nFabrik wo ich \nmeine LED’s \nfertigen lasse \nda er über viele \nJahre hinaus mit \nmir LED-Lösungen \numsetzt und \nimmer mir Rat \nund Tat zur \nSeite steht.\n\n"
+    "Meine Eltern \nweil Sie mich \nseit sehr vielen \nJahren nicht nur \nmoralisch \nunterstützen bei \nder Umsetzung \nder Projekte, \nsondern mir als \nFamilie immer \nwieder Rückhalt \ngeben!\n\n"
+    ,//txtAboutText
+    "Factory reset?",//txtFactoryReset
+    "Click to confirm.",//txtFactoryResetConfirm
+    "reset to ignore.",//txtFactoryResetIgnore
+    "Zeit anpassen",//txtTimeOffset,
+    "Datum einstellen",//txtSetDateTime,
+  };
+};
diff --git a/examples/console/src/lang/en.cpp b/examples/console/src/lang/en.cpp
new file mode 100644
index 00000000..638e4cd4
--- /dev/null
+++ b/examples/console/src/lang/en.cpp
@@ -0,0 +1,102 @@
+/* -*- C++ -*- */
+
+#include "../lang.h"
+namespace lang_en {
+  const char* lang[(int)TextId::nText]{
+    #ifdef HEADLESS
+      "MicroTC361",//  txtMain,
+    #else
+      "MicroTC360",//  txtMain,
+    #endif
+    "Exit",//txtExit
+    "<Back",//txtBack,
+    "Time",//  txtTime,
+    "On",// txtOn,
+    "Off",// txtOff,
+    "Yes",// txtYes,
+    "No",// txtNo,
+    "",//  txtLevel,
+    "",//  txtSched,
+    "Save",//  txtSave,
+    "Load",//txtLoad
+    "Led",//  txtLed,
+    "Light",//  txtLight,
+    "Settings",//txtSettings,
+    "Standby",//txtStandby,
+    "Wi-Fi",//txtWifi,
+    "Wi-Fi:",//txtWifiTog,
+    "Cloud:",//txtCloud,
+    "Thunderstorm:",//txtThunder,
+    "Moonlight",//txtMoon,
+    "Set Date/Time",//txtDateTime,
+    "Ok",//txtOk
+    "Cancel",//txtCancel
+    "no packet yet",//txtNoPack
+    "seconds since 1900",//txtSeconds1900
+    "use NTP:",//txtUseNTP
+    "Timezone GMT",//txtGMT
+    "(+add entry)",//txtAddEntry
+    "Auto schedule",//txtAutoSched
+    "Slot",//txtSlot
+    "Auto",//txtAuto
+    "Manual",//txtManual
+    "Control:",//txtControl
+    "Manual level",//txtManualLevel
+    "press [select]",//txtPressSelect
+    "to continue...",//txtToCont
+    "no WiFi found",//txtNoWifi
+    "Wifi error",//txtWifiError
+    "Scanning...",//txtScan
+    "no networks found",//txtNoNet
+    "select...",//txtSelect
+    "SSID:",//txtSSID
+    "Pwd",//txtPwd
+    "Connect",//txtConnect
+    "Disconnect",//txtDisconnect
+    "#1",//txtMoonChan1
+    "#2",//txtMoonChan2
+    "#3",//txtMoonChan3
+    "#4",//txtMoonChan4
+    "#5",//txtMoonChan5
+    "#6",//txtMoonChan6
+    "Saved.",//txtSavedOk
+    "Save error!",//txtSaveError
+    "Loaded",//txtLoadedOk
+    "Load error!",//txtLoadError,
+    "Connecting to:",//txtConWifi
+    "Pwd: ",//txtApPwd
+    "IP: ",//txtIP
+    "Access Point",//txtAccessPoint
+    "Backup",//txtBackup
+    "Restore",//txtRestore
+    "max",//txtCloudMax,
+    "max",//txtThunderMax,
+    "max",//txtMoonMax,
+    "Demo:",//txtDemo
+    "Getting date/time from web...", //txtNTPsync
+    "Daylight save:",//txtDLS,
+    "Date/Time set",//txtNTPset
+    "Language",//txtLang,
+    "Update...",//txtUpdate
+    "Reset!",//txtReset
+    "Using factory settings",//txtLCFactory
+    #ifdef HEADLESS
+      "About MicroTC361",//txtAbout
+    #else
+      "About MicroTC360",//txtAbout
+    #endif
+    "Credits:\n\n"
+    "At this point we \nwould like to \nthank everyone \nwho made this \nproject possible:\n\n"
+    "Rui Azevedo from \nr-site.net / \nArduinoMenu for \nhis help with \nprogramming the \nMicroTC360/1 \ncontroller, \ntesting and \ndebugging\n\n"
+    "Tobias Gawrisch \nfrom AquaOwner \nfor his ideas \nabout the \nUNIQ FS LED \nseries and the \nhelp with the \ndesign\n\n"
+    "Oliver L. of \nOcean Optics, \nwho has been \nsupporting me in \nLED research for \nmany years\n\n"
+    "Kable, Sales \nManager of the \nfactory where I \nmanufacture my \nLED's because he \nimplements LED \nsolutions with \nme for many \nyears and always \nsupports me with \nadvice and \nassistance.\n\n"
+    "My parents who \nsupported me for \nmany years, not \nonly morally \nduring the \nimplementation \nof projects, but \nback me up as \nfamily again and \nagain!\n\n"
+    ,//txtAboutText
+    "Factory reset?",//txtFactoryReset
+    "Click to confirm.",//txtFactoryResetConfirm
+    "reset to ignore.",//txtFactoryResetIgnore
+    "Time offset",//txtTimeOffset,
+    "Set date/time",//txtSetDateTime,
+  };
+};
\ No newline at end of file
diff --git a/examples/console/src/lang/pt.cpp b/examples/console/src/lang/pt.cpp
new file mode 100644
index 00000000..823fc7fb
--- /dev/null
+++ b/examples/console/src/lang/pt.cpp
@@ -0,0 +1,102 @@
+/* -*- C++ -*- */
+
+#include "../lang.h"
+namespace lang_pt {
+  const char* lang[nText]{
+    #ifdef HEADLESS
+      "MicroTC361",//  txtMain,
+    #else
+      "MicroTC360",//  txtMain,
+    #endif
+    "Sair",//txtExit
+    "<Voltar",//txtBack,
+    "Hora",//  txtTime,
+    "Ligado",// txtOn,
+    "Desligado",// txtOff,
+    "Sim",// txtYes,
+    "Não",// txtNo,
+    "",//  txtLevel,
+    "",//  txtSched,
+    "Guardar",//  txtSave,
+    "Carregar",//txtLoad
+    "Led",//  txtLed,
+    "Luz",//  txtLight,
+    "Parametros",//txtSettings,
+    "Inactivo",//txtStandby,
+    "Wi-Fi",//txtWifi,
+    "Wi-Fi:",//txtWifiTog,
+    "Nuvens:",//txtCloud,
+    "Relampagos:",//txtThunder,
+    "Luar",//txtMoon,
+    "Data e Hora",//txtDateTime,
+    "Aplicar",//txtOk
+    "Cancelar",//txtCancel
+    "sem resposta",//txtNoPack
+    "segundos desde 1900",//txtSeconds1900
+    "use NTP:",//txtUseNTP
+    "fuso horário GMT",//txtGMT
+    "(+adicionar item)",//txtAddEntry
+    "Horário automático",//txtAutoSched
+    "Entrada",//txtSlot
+    "Auto",//txtAuto
+    "Manual",//txtManual
+    "Controlo:",//txtControl
+    "Nível manual",//txtManualLevel
+    "[clique]",//txtPressSelect
+    "para continuar...",//txtToCont
+    "WiFi não encontrado",//txtNoWifi
+    "Erro Wifi",//txtWifiError
+    "Procurar...",//txtScan
+    "Sem redes",//txtNoNet
+    "selecione...",//txtSelect
+    "SSID:",//txtSSID
+    "Chave",//txtPwd
+    "Ligar",//txtConnect
+    "Desligar",//txtDisconnect,
+    "#1",//txtMoonChan1
+    "#2",//txtMoonChan2
+    "#3",//txtMoonChan3
+    "#4",//txtMoonChan4
+    "#5",//txtMoonChan5
+    "#6",//txtMoonChan6
+    "Guardado.",//txtSavedOk
+    "Erro ao guardar!",//txtSaveError
+    "Carregado",//txtLoadedOk
+    "Erro ao carregar!",//txtLoadError,
+    "Ligando a:",//txtConWifi
+    "Chave: ",//txtApPwd
+    "IP: ",//txtIP
+    "Ponto de acesso",//txtAccessPoint
+    "Armazenar",//txtBackup
+    "Recuperar",//txtRestore
+    "max",//txtCloudMax,
+    "max",//txtThunderMax,
+    "max",//txtMoonMax,
+    "Demo:",//txtDemo
+    "A obter data/hora da net...", //txtNTPsync
+    "Hora de verão:",//txtDLS,
+    "Data/Hora acertada",//txtNTPset
+    "Lingua",//txtLang,
+    "Actualizar...",//txtUpdate
+    "Reverter!",//txtReset
+    "Usando configurações de fabrica.",//txtLCFactory
+    #ifdef HEADLESS
+      "Acerca MicroTC361",//txtAbout
+    #else
+      "Acerca MicroTC360",//txtAbout
+    #endif
+    "Créditos:\n\n"
+    "Agradecemos a \ntodos os que \ntornaram este \nprojeto possível:\n\n"
+    "Rui Azevedo da \nr-site.net / \nArduinoMenu por \nsua ajuda na \nprogramação do \ncontrolador \nMicroTC360/1, \ntestes e \ndepuração\n\n"
+    "Tobias Gawrisch \nda AquaOwner \npelas suas \nideias sobre a \nsérie LED \nUNIQ FS e a \najuda com o \ndesign\n\n"
+    "Oliver L., da \nOcean Optics, \nque há muitos \nanos me apoia na \npesquisa de LEDs\n\n"
+    "Kable, Gerente \nde Vendas da \nfábrica onde eu \nfabrico os meus \nLED's porque ele \nimplementa \nsoluções de LED \ncomigo há muitos \nanos e sempre me \napoia com \nconselhos e \nassistência.\n\n"
+    "Meus pais que me \napoiarem por \nmuitos anos, não \napenas \nmoralmente \ndurante a \nimplementação de \nprojetos, mas \ntambém como uma \nfamília!\n\n"
+    ,//txtAboutText
+    "Config. de fábrica",//txtFactoryReset
+    "Click p/confirmar",//txtFactoryResetConfirm
+    "reset p/ignorar.",//txtFactoryResetIgnore
+    "Ajuste horário",//txtTimeOffset,
+    "Aplicar data/hora",//txtSetDateTime,
+  };
+};
diff --git a/examples/console/src/main.cpp b/examples/console/src/main.cpp
new file mode 100644
index 00000000..7f201f75
--- /dev/null
+++ b/examples/console/src/main.cpp
@@ -0,0 +1,364 @@
+#include <menu.h>
+#include <menu/sys/stdMenu.h>
+#include <menu/IO/linuxKeyIn.h>
+#include <menu/IO/pcArrows.h>
+#include <menu/in.h>
+#include <menu/nav.h>
+#include "lang.h"
+#include <array>
+#include <initializer_list>
+using namespace Menu;
+using namespace std;
+
+#ifdef ARDUINO
+  template<decltype(Serial)& dev=Serial>
+  struct SerialOut {
+    template<typename O>
+    void print(O o) {dev.print(o);}
+    void nl() {dev.println();}
+  };
+#else
+  #include <iostream>
+  using namespace std;
+  #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
+#endif
+
+#include <menu/IO/stdOut.h>
+
+template<typename O=Nil> 
+struct Native:O {
+  using Idx=size_t;
+};
+template<typename Cfg>
+struct Config {
+  template<typename O=Nil>
+  struct Part:Cfg,O {
+  };
+};
+
+using Cfg=Config<Native<>>;
+CONFIG_MENU_LIB(Cfg)
+
+using Out=OutDef<
+  OnFmt<Fmt::Title,PrintWrap<>::Part>::Part,
+  RangePanel<5>::Part,
+  TitlePrinter::Part,
+  BodyPrinter::Part,
+  BasePrinter::Part,
+  TextEditMode::Part,
+  TextFmt::Part,//format translation
+  // FullPrinter::Part,//format emit
+  // XmlFmt::Part,
+  StdOut::Part//raw output device
+>; Out out;
+
+using IMenuOut=OutDef<
+  MenuOut::Part,
+  FullPrinter::Part,//format emit
+  TextFmt::Part,//format translation
+  // XmlFmt::Part,
+  StdOut::Part//raw output device
+>;
+IMenuOut iOut;
+
+//-------------------------
+
+// Langs selectedLang=Langs::en;
+// template<TextId id>
+// struct Lang {
+//   template<typename O=Empty<Nil>>
+//   struct Part:O {
+//     using Base=O;
+//     using This=Part<Base>;
+//     using Base::Base;
+//     template<typename Out>
+//     void printTo(Nav& nav,Out o) {
+//       o.print(langs[selectedLang][id]);
+//       Base::printTo(o);
+//     }
+//   };
+// };
+
+//dynamic text
+Text::Part<> op1("op1");
+
+// Lang<txtOk>::Part<> ok;
+
+bool menu_action() {
+  cout<<"menu action called\r"<<endl;
+  return false;
+}
+
+bool submenu_action() {
+  cout<<"sub-menu action called\r"<<endl;
+  return true;
+}
+
+bool op1_action() {
+  cout<<"op 1 action.\r"<<endl;
+  return false;
+}
+
+bool op2_action() {
+  cout<<"op 2 action.\r"<<endl;
+  return false;
+}
+
+bool sub1_action() {
+  cout<<"sub 1 action.\r"<<endl;
+  return true;
+}
+
+bool sub2_action() {
+  cout<<"sub 2 action.\r"<<endl;
+  return false;
+}
+
+bool imain_action() {
+  cout<<"iMainMenu action.\r"<<endl;
+  return true;
+}
+
+bool tog12_action();
+
+bool running=true;
+int perc=50;
+bool quit() {return running=false;}
+
+ConstText quit_text="<Quit!";
+using Quit=ItemDef<Action<quit>::Part,StaticText<&quit_text>::Part>;
+using IQuit=ItemDef<Prompt::Part,Action<quit>::Part,StaticText<&quit_text>::Part>;
+
+ConstText exit_text="<Exit";
+using Exit=ItemDef<StaticText<&exit_text>::Part>;
+using IExit=ItemDef<Prompt::Part,StaticText<&exit_text>::Part>;
+
+ConstText title_text="Main menu";
+ConstText op2_text="op2";
+ConstText tog12_text="Toggle En/Dis";
+ConstText opn_text="...";
+ConstText celsius="℃ ";
+ConstText addr_label="Address";
+
+ConstText op1_text="op1";
+ConstText temp_text="Temp.";
+ConstText subMenu_title_text="Sub-menu";
+ConstText sub1_text="Sub op 1";
+ConstText sub2_text="Sub op 2";
+
+ConstText trig_text="Trigger";
+ConstText trig0_text="None";
+ConstText trig1_text="Rise";
+ConstText trig2_text="Fall";
+ConstText trig3_text="Both";
+enum class Trig {None,Rise,Fall,Both};
+// template<typename O>
+// O& operator<<(O& out,Trig t) {
+//   switch(t) {
+//     case Trig::None:return out<<"None";
+//     case Trig::Rise:return out<<"Rise";
+//     case Trig::Fall:return out<<"Fall";
+//     case Trig::Both:return out<<"Both";
+//     default: return out;
+//   }
+// }
+Trig trig=Trig::None;
+
+char addr_buffer[]="000";//buffer to be edited
+const char* addr_mask[]={"0123456789ABCDEF"};//edit mask for previous buffer
+const char* ox="0x";//hex prefix
+
+using TrigOptions=StaticMenuBody<
+  ItemDef<StaticText<&trig0_text>::Part,Value<Trig,Trig::None>::Part>
+  ,ItemDef<StaticText<&trig1_text>::Part,Value<Trig,Trig::Rise>::Part>
+  // ,ItemDef<StaticText<&trig2_text>::Part,Value<Trig,Trig::Fall>::Part>
+  // ,ItemDef<StaticText<&trig3_text>::Part,Value<Trig,Trig::Both>::Part>
+>;
+
+using MainMenu=StaticMenu<
+  ItemDef<StaticText<&title_text>::Part>,
+  WrapNav::Part<//this menu will wrap
+    StaticMenuBody<
+      ItemDef<EnDis<true>::Part,Action<op1_action>::Part,StaticText<&op1_text>::Part>
+      ,ItemDef<EnDis<false>::Part,Action<op2_action>::Part,StaticText<&op2_text>::Part>
+      ,ItemDef<Action<tog12_action>::Part,StaticText<&tog12_text>::Part>
+      ,ItemDef<
+        StaticLabel<&addr_label>::Part,
+        AsEditMode::Part,
+        StaticText<&ox>::Part,//some special text between the cursor and the data
+        AsValue::Part,
+        TextEditBase<addr_buffer,sizeof(addr_buffer)/sizeof(addr_label[0]),addr_mask>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&trig_text>::Part
+        ,AsValue::Part 
+        ,Toggle<
+          StaticMenu<
+            ItemDef<StaticLabel<&trig_text>::Part>::Part,
+            WrapNav::Part<TrigOptions>
+          >
+        >::Part
+        ,FieldRef<Trig,trig,Trig::None>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&trig_text>::Part
+        ,AsEditMode::Part
+        ,AsValue::Part
+        ,Select<
+          StaticMenu<
+            ItemDef<StaticLabel<&trig_text>::Part>::Part
+            ,WrapNav::Part<TrigOptions>
+          >
+        >::Part
+        ,FieldRef<Trig,trig,Trig::None>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&trig_text>::Part
+        ,AsEditMode::Part
+        ,AsValue::Part 
+        ,Choose<
+          StaticMenu<
+            ItemDef<StaticLabel<&trig_text>::Part>
+            ,TrigOptions
+          >
+        >::Part
+        ,FieldRef<Trig,trig,Trig::None>::Part
+      >
+      ,ItemDef<
+        StaticLabel<&temp_text>::Part
+        ,AsEditMode::Part
+        ,AsValue::Part
+        ,Chain<
+          NumRef<decltype(perc),perc>::Part,
+          StaticSTRange<decltype(perc),0,100,10,1>::Part
+        >::Part
+        ,AsUnit::Part
+        ,StaticText<&celsius>::Part
+      >
+      ,Action<submenu_action>::Part<
+        StaticMenu<
+          ItemDef<StaticText<&subMenu_title_text>::Part>
+          ,StaticMenuBody<
+            ItemDef<Action<sub1_action>::Part,StaticText<&sub1_text>::Part>
+            ,ItemDef<Action<sub2_action>::Part,StaticText<&sub2_text>::Part>
+            ,ItemDef<StaticText<&opn_text>::Part>
+            ,ItemDef<StaticText<&opn_text>::Part>
+            ,Exit
+          >
+        >
+      >
+      ,ItemDef<StaticText<&opn_text>::Part>
+      ,Quit
+    >
+  >
+>;
+
+MainMenu mainMenu;
+
+// togle enable/disable on first 2 options
+bool tog12_action() {
+  // _trace(mdo<<"toggling 1&2\n\r");
+  bool en1=Path<0>().walk<MainMenu,Enabled>(mainMenu);
+  bool en2=Path<1>().walk<MainMenu,Enabled>(mainMenu);
+  Path<0>().walk<MainMenu,Enable,bool>(mainMenu,!en1);
+  Path<1>().walk<MainMenu,Enable,bool>(mainMenu,!en2);
+  return true;
+}
+
+
+// ConstText std_sub="std sub menu";
+// using StdSub=ItemDef<Prompt::Part,StdMenu<array<IItem*,3>>::Part,StaticText<&std_sub>::Part>;
+// StdSub stdSub{
+//   new ItemDef<Prompt::Part,Action<sub1_action>::Part,Text::Part>("sub 1"),
+//   new ItemDef<Prompt::Part,Action<sub2_action>::Part,Text::Part>("sub 2"),
+//   new IExit()
+// };
+
+// ConstText std_title="array menu";
+// using IMainMenu=ItemDef<
+//   Prompt::Part,
+//   StdMenu<array<IItem*,4>>::Part,
+//   Action<imain_action>::Part,
+//   StaticText<&std_title>::Part
+// >;
+
+// IMainMenu iMainMenu{
+//   new ItemDef<Prompt::Part,Action<op1_action>::Part,Text::Part>("Yupi!"),
+//   new ItemDef<Prompt::Part,Action<op2_action>::Part,Text::Part>(".zZZz."),
+//   &stdSub,
+//   new IQuit()
+// };
+
+// ItemDef<Prompt::Part,Text::Part> test("ok");
+
+//navigation API
+using Nav=NavDef<StaticNav<MainMenu,4>::Part>;
+Nav nav(mainMenu);
+
+// NavDef<StaticNav<IMainMenu,3>::Part> iNav(iMainMenu);
+//menu input --------------------------------------
+InDef<
+  LinuxKeyIn::Part,
+  PCArrows::Part
+> in;
+
+// using EnFld=ItemDef<
+//   Choose<
+//     StaticMenu<
+//       ItemDef<AsLabel<StaticText<&trig_text>::Part>::Part>::Part
+//       ,StaticMenuBody<
+//         ItemDef<StaticText<&trig0_text>::Part,Value<Trig,Trig::None>::Part>
+//         ,ItemDef<StaticText<&trig1_text>::Part,Value<Trig,Trig::Rise>::Part>
+//         ,ItemDef<StaticText<&trig2_text>::Part,Value<Trig,Trig::Fall>::Part>
+//         ,ItemDef<StaticText<&trig3_text>::Part,Value<Trig,Trig::Both>::Part>
+//       >
+//     >
+//   >::Part,
+//   // FieldRef<Trig,trig,Trig::None>::Part
+//   AsValue< 
+//     FieldRef<Trig,trig,Trig::None>::Part
+//   >::Part
+// >;
+
+// EnFld enFld;
+
+// void inspect(Idx l,Idx* path) {
+//   PathRef ref(l,path);
+//   mdo<<"inpecting path "<<ref;
+//   mdo<<" Styles:"<<ref.template walk<MainMenu,Styles>(mainMenu)<<" ";
+//   ref.template walk<MainMenu,PrintTo,Nav&,Out&,bool,bool>(mainMenu,nav,out,false,false);
+//   mdo<<"\n\r";
+// }
+
+// using Test=ItemDef<
+//   // AsLabel<StaticText<&addr_label>::Part>::Part,
+//   TextEdit<addr_buffer,sizeof(addr_buffer),addr_mask>::Part
+// >;
+
+int main() {
+  // Idx p[]{};
+  // Idx p0[]{0};
+  // Idx p1[]{1};
+  // Idx p01[]{0,1};
+  // Idx p11[]{0,1};
+  // inspect(0,p);
+  // inspect(1,p0);
+  // inspect(1,p1);
+  // inspect(2,p01);
+
+  // PathRef(2,p11).template walk<MainMenu,PrintTo,Nav&,Out&>(mainMenu,nav,out,0,true);
+  // PathRef(nav.level,nav.path).template walk<MainMenu,PrintMenuTo,Nav&,Out&,bool,bool,int>(mainMenu,nav,out,nav.focus(),nav.tune(),0);
+  // PrintMenuTo().template operator()<MainMenu,Nav&,Out&>(mainMenu,nav,out,nav.focus(),nav.tune(),0);
+
+  // Test().template printTo<decltype(nav),decltype(out),true>(nav,out,false,false);
+  nav.printTo(out);
+  while(running) if(nav.doInput(in)) {nav.printTo(out);out.nl();}
+
+  // running=true;
+  // iNav.printTo(iOut);
+  // while(running) if(iNav.doInput(in)) iNav.printTo(iOut);
+
+  // enFld.printTo(out);
+  // enFld.cmd<Cmd::Enter>();
+  return 0;
+}
diff --git a/examples/console/test/README b/examples/console/test/README
new file mode 100644
index 00000000..b94d0890
--- /dev/null
+++ b/examples/console/test/README
@@ -0,0 +1,11 @@
+
+This directory is intended for PlatformIO Unit Testing and project tests.
+
+Unit Testing is a software testing method by which individual units of
+source code, sets of one or more MCU program modules together with associated
+control data, usage procedures, and operating procedures, are tested to
+determine whether they are fit for use. Unit testing finds problems early
+in the development cycle.
+
+More information about PlatformIO Unit Testing:
+- https://docs.platformio.org/page/plus/unit-testing.html
diff --git a/examples/customField/.gitignore b/examples/customField/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/customField/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/customField/.travis.yml b/examples/customField/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/customField/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/customField/customField/customField.ino b/examples/customField/customField/customField.ino
deleted file mode 100644
index 420a79dd..00000000
--- a/examples/customField/customField/customField.ino
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <Arduino.h>
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-// #include <Streaming.h>
-
-using namespace Menu;
-
-int test=55;
-
-//custom field edit
-//implementing a customized menu component
-// --this components can be latter shared as plugins
-// is already stored as a plugin
-template<typename T>
-class cancelField:public menuField<T> {
-protected:
-  T original;//to use when canceling
-  bool editing;
-public:
-  cancelField(constMEM menuFieldShadow<T>& shadow):menuField<T>(shadow),editing(false) {}
-  void doNav(navNode& nav,navCmd cmd) override {
-    if (!editing) {
-      original=menuField<T>::target();
-      editing=true;
-    }
-    switch(cmd.cmd) {
-      case escCmd:
-        editing=false;
-        menuField<T>::target()=original;
-        menuField<T>::tunning=true;
-        break;
-      case enterCmd:
-        if (menuField<T>::tunning||nav.root->nav2D||!menuField<T>::tune())
-          editing=false;
-        break;
-      default: break;
-    }
-    menuField<T>::doNav(nav,cmd);
-  }
-};
-
-//a menu using a customized components
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,altFIELD(cancelField,test,"Custom edit","%",0,100,10,1,doNothing,enterEvent,wrapStyle)
-  ,FIELD(test,"Original edit","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-);
-
-#define MAX_DEPTH 1
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x testing custom fields");
-  Serial.flush();
-}
-
-void loop() {
-  nav.poll();
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/customField/platformio.ini b/examples/customField/platformio.ini
deleted file mode 100644
index 7d5568c0..00000000
--- a/examples/customField/platformio.ini
+++ /dev/null
@@ -1,32 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=customField
-lib_dir=~/Arduino/Libraries
-
-[env:nanoatmega328]
-platform = atmelavr
-board = nanoatmega328
-framework = arduino
-upload_port=/dev/ttyUSB*
-upload_flags=-V
-build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
-
-; [env:uno]
-; platform=atmelavr
-; board=uno
-; framework=arduino
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -Wno-switch -lstdc++
diff --git a/examples/dynamic/dynamic/dynamic.ino b/examples/dynamic/dynamic/dynamic.ino
deleted file mode 100644
index 5d55365e..00000000
--- a/examples/dynamic/dynamic/dynamic.ino
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-dynamic menu tests (experimental)
-
-this is a somehow dynamic menu, its ok to use it on non AVR's
-or with USE_RAM defined
-
-the dynamic support is somehow limited
-we do not support adding or removing options
-however changing the list of options should be allowed
-
-or replacing options
-
-the user is responsible for all option allocation
-deleting them if created with new, etc...
-
-this can turn out to be a mess
-
-objects construction is not realy tested beyond this example
-please let me know if you have any interest on this kind of things
-
-this is nice to support dynamic options like a list of detected wifi networks
-or a list of files+folders from a folder/file system
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-// #include <Streaming.h>
-
-using namespace Menu;
-
-#ifndef LED_BUILTIN
-  #define LED_BUILTIN 13
-#endif
-
-#define LED LED_BUILTIN
-
-#ifndef USING_RAM
-#error "This menu example does not work on flash memory versions (MENU_USEPGM)"
-#error "Library must be compiled with MENU_USERAM defined (default for non AVR's)"
-#error "ex: passing -DMENU_USERAM to the compiler"
-#endif
-
-//choose field and options -------------------------------------
-int duration=0;//target var
-prompt* durData[]={
-  new menuValue<int>("Off",0),
-  new menuValue<int>("Short",1),
-  new menuValue<int>("Medium",2),
-  new menuValue<int>("Long",3)
-};
-choose<int>& durMenu =*new choose<int>("Duration",duration,sizeof(durData)/sizeof(prompt*),durData);
-
-//select field and options -------------------------------------
-enum Fxs {Fx0,Fx1,Fx2} selFx;//target var
-prompt* fxData[]={
-  new menuValue<Fxs>("Default",Fx0),
-  new menuValue<Fxs>("Pop",Fx1),
-  new menuValue<Fxs>("Rock",Fx2)
-};
-Menu::select<Fxs>& fxMenu =*new Menu::select<Fxs>("Fx",selFx,sizeof(fxData)/sizeof(prompt*),fxData);
-
-//toggle field and options -------------------------------------
-bool led=false;//target var
-void setLed() {digitalWrite(LED,!led);}
-prompt* togData[]={
-  new menuValue<bool>("On",true),
-  new menuValue<bool>("Off",false)
-};
-toggle<bool>& ledMenu
-  =*new toggle<bool>("LED:",led,sizeof(togData)/sizeof(prompt*),togData,(Menu::callback)setLed,enterEvent);
-
-//the submenu -------------------------------------
-prompt* subData[]={
-  new prompt("Sub1"),
-  new prompt("Sub2"),
-  new Exit("<Back")
-};
-menuNode& subMenu=*new menuNode("sub-menu",sizeof(subData)/sizeof(prompt*),subData);
-
-//pad menu --------------------
-uint16_t year=2017;
-uint16_t month=10;
-uint16_t day=7;
-
-prompt* padData[]={
-  new menuField<typeof(year)>(year,"","",1900,3000,20,1,doNothing,noEvent),
-  new menuField<typeof(month)>(month,"/","",1,12,1,0,doNothing,noEvent),
-  new menuField<typeof(day)>(day,"/","",1,31,1,0,doNothing,noEvent)
-};
-menuNode& padMenu=*new menuNode(
-  "Date",
-  sizeof(padData)/sizeof(prompt*),
-  padData,
-  doNothing,
-  noEvent,
-  noStyle,
-  (systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
-);
-
-//the main menu -------------------------------------
-void op1Func() {Serial.println("Op 1 executed");}
-uint8_t test=55;//target var for numerical range field
-
-//edit text field info
-const char* hexDigit MEMMODE="0123456789ABCDEF";//a text table
-const char* hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};//text validators
-char buf1[]="0x11";//text edit target
-
-prompt* mainData[]={
-  new prompt("Op 1",(Menu::callback)op1Func,enterEvent),
-  new prompt("Op 2"),//we can set/change text, function and event mask latter
-  new menuField<typeof(test)>(test,"Bright","",0,255,10,1,doNothing,noEvent),
-  new textField("Addr",buf1,4,hexNr),
-  &subMenu,
-  &durMenu,
-  &fxMenu,
-  &ledMenu,
-  &padMenu,
-  new Exit("<Exit.")
-};
-menuNode& mainMenu=*new menuNode("Main menu",sizeof(mainData)/sizeof(prompt*),mainData/*,doNothing,noEvent,wrapStyle*/);
-
-#define MAX_DEPTH 2
-
-//input -------------------------------------
-serialIn in(Serial);
-
-//serial output -------------------------------------
-idx_t tops[MAX_DEPTH];
-serialOut out(Serial,tops);
-
-//outputs -------------------------------------
-menuOut* constMEM outList[] MEMMODE={&out};
-outputsList outs(outList,sizeof(outList)/sizeof(menuOut*));
-
-//navigation control -------------------------------------
-navNode path[MAX_DEPTH];
-navRoot nav(mainMenu,path,MAX_DEPTH,in,outs);
-
-void setup() {
-  pinMode(LED,OUTPUT);
-  setLed();
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("press any key...");
-  while(!Serial.available());
-  Serial.println("menu 4.x test");
-  Serial.flush();
-  mainMenu[0].shadow->text="Changed";
-}
-
-void loop() {
-  nav.poll();//this device only draws when needed
-  if(nav.sleepTask) {
-    Serial.println();
-    Serial.println("menu is suspended");
-    Serial.println("presse [select] to resume.");
-  }
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/esp8266/EscControl/EscControl/EscControl.ino b/examples/esp8266/EscControl/EscControl/EscControl.ino
deleted file mode 100644
index 2a88be75..00000000
--- a/examples/esp8266/EscControl/EscControl/EscControl.ino
+++ /dev/null
@@ -1,357 +0,0 @@
-/********************
-Arduino generic menu system
-
-Feb. 2019 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-IMPORTANT!:
-this requires the data folder to be stored on esp8266 spiff
-Extra libraries should be present
-
-arduinoWebSockets - https://github.com/Links2004/arduinoWebSockets
-ESP8266WiFi - https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi
-ESP8266WebServer - https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer
-
-*/
-#include <Servo.h>
-
-#include <menu.h>
-#include <menuIO/esp8266Out.h>
-#include <menuIO/xmlFmt.h>//to write a menu has html page
-#include <menuIO/serialIn.h>
-#include <menuIO/xmlFmt.h>//to write a menu has xml page
-#include <menuIO/jsonFmt.h>//to write a menu has xml page
-#ifndef ARDUINO_STREAMING
-  #include <streamFlow.h>//https://github.com/neu-rah/streamFlow
-#else
-  #include <Streaming.h>//https://github.com/scottdky/Streaming
-#endif
-//#include <menuIO/jsFmt.h>//to send javascript thru web socket (live update)
-#include <FS.h>
-#include <Hash.h>
-extern "C" {
-  #include "user_interface.h"
-}
-
-using namespace Menu;
-
-#ifdef WEB_DEBUG
-  // on debug mode I put aux files on external server to allow changes without SPIFF update
-  // on this mode the browser MUST be instructed to accept cross domain files
-  String xslt("http://neurux:8080/");
-#else
-  String xslt("");
-#endif
-
-menuOut& operator<<(menuOut& o,unsigned long int i) {
-  o.print(i);
-  return o;
-}
-menuOut& operator<<(menuOut& o,endlObj) {
-  o.println();
-  return o;
-}
-
-//this version number MUST be the same as data/*
-#define CUR_VERSION "1.5"
-#define APName "EscControl"
-
-#define ESCPIN 2
-Servo myservo;
-
-#ifndef MENU_SSID
-  #error "need to define WiFi SSID here"
-  #define MENU_SSID "r-site.net"
-#endif
-#ifndef MENU_PASS
-  #error "need to define WiFi password here"
-  #define MENU_PASS ""
-#endif
-
-// char wifiSSID[wifiSSIDLen+1];//="                                ";
-// char wifiPwd [wifiPwdLen+1];//="                                ";
-
-const char* ssid = MENU_SSID;
-const char* password = MENU_PASS;
-// const char* serverName="192.168.1.79";
-
-#define HTTP_PORT 80
-#define WS_PORT 81
-#define USE_SERIAL Serial
-ESP8266WebServer server(80);
-WebSocketsServer webSocket(81);
-
-#define MAX_DEPTH 2
-idx_t web_tops[MAX_DEPTH];
-PANELS(webPanels,{0,0,80,100});
-xmlFmt<esp8266_WebServerStreamOut> serverOut(server,web_tops,webPanels);
-jsonFmt<esp8266_WebServerStreamOut> jsonOut(server,web_tops,webPanels);
-jsonFmt<esp8266BufferedOut> wsOut(web_tops,webPanels);
-
-int speed=0;
-result setEsc() {
-  myservo.write(map(speed,0,100,90,170));//this parameters are for my esc, please adapt
-}
-result armEsc() {
-  // arm the speed controller, modify as necessary for your ESC
-  speed=0;
-  setEsc();
-  delay(1000); //delay 1 second,  some speed controllers may need longer
-  Serial.println("arming ESC");
-  serverOut<<"arming ESC<br/>";
-  return proceed;
-}
-result stopEsc() {
-  speed=0;
-  setEsc();
-  Serial.println("ESC stop");
-  serverOut<<"ESC stop<br/>";
-  return proceed;
-}
-
-//the menu
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Stop",stopEsc,enterEvent)
-  ,OP("Arm",armEsc,enterEvent)
-  ,FIELD(speed,"Speed","%",0,100,10,1, setEsc, enterEvent, noStyle)
-  ,EXIT("Exit!")
-);
-
-result idle(menuOut& o,idleEvent e) {
-  //if (e==idling)
-  Serial.println("suspended");
-  o<<"suspended..."<<endl<<"press [select]"<<endl<<"to continue"<<endl<<(millis()%1000);
-  return quit;
-}
-
-template<typename T>//some utill to help us calculate array sizes (known at compile time)
-constexpr inline size_t len(T& o) {return sizeof(o)/sizeof(decltype(o[0]));}
-
-//serial menu navigation
-MENU_OUTLIST(out,&serverOut);
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-//xml+http navigation control
-noInput none;//web uses its own API
-menuOut* web_outputs[]={&serverOut};
-outputsList web_out(web_outputs,len(web_outputs));
-navNode web_cursors[MAX_DEPTH];
-navRoot webNav(mainMenu, web_cursors, MAX_DEPTH, none, web_out);
-
-//json+http navigation control
-menuOut* json_outputs[]={&jsonOut};
-outputsList json_out(json_outputs,len(json_outputs));
-navNode json_cursors[MAX_DEPTH];
-navRoot jsonNav(mainMenu, json_cursors, MAX_DEPTH, none, json_out);
-
-//websockets navigation control
-menuOut* ws_outputs[]={&wsOut};
-outputsList ws_out(ws_outputs,len(ws_outputs));
-navNode ws_cursors[MAX_DEPTH];
-navRoot wsNav(mainMenu, ws_cursors, MAX_DEPTH, none, ws_out);
-
-//config myOptions('*','-',defaultNavCodes,false);
-
-void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
-  switch(type) {
-    case WStype_DISCONNECTED:
-      //USE_SERIAL.printf("[%u] Disconnected!\n", num);
-      break;
-    case WStype_CONNECTED: {
-        IPAddress ip = webSocket.remoteIP(num);
-        //USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
-        webSocket.sendTXT(num, "console.log('ArduinoMenu Connected')");
-      }
-      break;
-    case WStype_TEXT: {
-        //USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
-        // nav.async((const char*)payload);//this is slow!!!!!!!!
-        __trace(Serial.printf("[%u] get Text: %s\n", num, payload));
-        char*s=(char*)payload;
-        _trace(Serial<<"serve websocket menu"<<endl);
-        wsOut.response.remove(0);
-        wsOut<<"{\"output\":\"";
-        wsNav.async((const char*)payload);
-        wsOut<<"\",\n\"menu\":";
-        wsNav.doOutput();
-        wsOut<<"\n}";
-        webSocket.sendTXT(num,wsOut.response);
-        // wsOut.response.remove(0);
-        // jsonEnd();
-      } break;
-    case WStype_BIN: {
-        USE_SERIAL<<"[WSc] get binary length:"<<length<<"[";
-        for(int c=0;c<length;c++) {
-          USE_SERIAL.print(*(char*)(payload+c),HEX);
-          USE_SERIAL.write(',');
-        }
-        USE_SERIAL<<"]"<<endl;
-        uint16_t id=*(uint16_t*) payload++;
-        idx_t len=*((idx_t*)++payload);
-        idx_t* pathBin=(idx_t*)++payload;
-        const char* inp=(const char*)(payload+len);
-        //Serial<<"id:"<<id<<endl;
-        if (id==nav.active().hash()) {
-          //Serial<<"id ok."<<endl;Serial.flush();
-          //Serial<<"input:"<<inp<<endl;
-          //StringStream inStr(inp);
-          //while(inStr.available())
-          nav.doInput(inp);
-          webSocket.sendTXT(num, "binBusy=false;");//send javascript to unlock the state
-        } //else Serial<<"id not ok!"<<endl;
-        //Serial<<endl;
-      }
-      break;
-    default:break;
-  }
-}
-
-void pageStart() {
-  _trace(Serial<<"pasgeStart!"<<endl);
-  serverOut<<"HTTP/1.1 200 OK\r\n"
-    <<"Content-Type: text/xml\r\n"
-    <<"Connection: close\r\n"
-    <<"Expires: 0\r\n"
-    <<"\r\n";
-  serverOut<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n"
-    "<?xml-stylesheet type=\"text/xsl\" href=\"";
-  serverOut<<xslt;
-  serverOut<<CUR_VERSION"/device.xslt";
-  serverOut<<"\"?>\r\n<menuLib"
-    #ifdef WEB_DEBUG
-      <<" debug=\"yes\""
-    #endif
-    <<" host=\"";
-    serverOut.print(APName);
-    serverOut<<"\">\r\n<sourceURL ver=\"" CUR_VERSION "/\">";
-  if (server.hasHeader("host"))
-    serverOut.print(server.header("host"));
-  else
-    serverOut.print(APName);
-  serverOut<<"</sourceURL>";
-}
-
-void pageEnd() {
-  serverOut<<"</menuLib>";
-  server.client().stop();
-}
-
-void jsonStart() {
-  _trace(Serial<<"jsonStart!"<<endl);
-  serverOut<<"HTTP/1.1 200 OK\r\n"
-    <<"Content-Type: application/json; charset=utf-8\r\n"
-    <<"Connection: close\r\n"
-    <<"Expires: 0\r\n"
-    <<"\r\n";
-}
-
-void jsonEnd() {
-  server.client().stop();
-}
-
-bool handleMenu(navRoot& nav){
-  _trace(
-    uint32_t free = system_get_free_heap_size();
-    Serial.print(F("free memory:"));
-    Serial.print(free);
-    Serial.print(F(" handleMenu "));
-    Serial.println(server.arg("at").c_str());
-  );
-  String at=server.arg("at");
-  bool r;
-  r=nav.async(server.hasArg("at")?at.c_str():"/");
-  return r;
-}
-
-//redirect to version folder,
-//this allows agressive caching with no need to cache reset on version change
-auto mainPage= []() {
-  _trace(Serial<<"serving main page from root!"<<endl);
-  server.sendHeader("Location", CUR_VERSION "/index.html", true);
-  server.send ( 302, "text/plain", "");
-  if (server.hasArg("at"))
-    nav.async(server.arg("at").c_str());
-};
-
-void setup(){
-  Serial.begin(115200);
-  while(!Serial);
-
-  myservo.attach(ESCPIN);
-
-  webNav.canExit=false;
-  jsonNav.canExit=false;
-  wsNav.canExit=false;
-
-  for(uint8_t t = 4; t > 0; t--) {
-      Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
-      Serial.flush();
-      delay(1000);
-  }
-
-  Serial.println();
-  Serial.println("Arduino menu webserver example");
-
-  SPIFFS.begin();
-
-  Serial.print("Connecting to ");
-  Serial.println(ssid);
-
-  WiFi.begin(ssid, password);
-  // Wait for connection
-  while (WiFi.status() != WL_CONNECTED) {
-    delay(500);
-    Serial.print(".");
-  }
-  webSocket.begin();
-  Serial.println("");
-  webSocket.onEvent(webSocketEvent);
-  Serial.println("Connected.");
-  Serial.print("IP address: ");
-  Serial.println(WiFi.localIP());
-
-  webSocket.begin();
-
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-
-  server.on("/",HTTP_GET,mainPage);
-
-  //menu xml server over http
-  server.on("/menu", HTTP_GET, []() {
-    pageStart();
-    serverOut<<"<output state=\""<<((int)&webNav.idleTask)<<"\"><![CDATA[";
-    _trace(Serial<<"output count"<<webNav.out.cnt<<endl);
-    handleMenu(webNav);//do navigation (read input) and produce output messages or reports
-    serverOut<<"]]></output>";
-    webNav.doOutput();
-    pageEnd();
-  });
-
-  //menu json server over http
-  server.on("/json", HTTP_GET, []() {
-    _trace(Serial<<"json request!"<<endl);
-    jsonStart();
-    serverOut<<"{\"output\":\"";
-    handleMenu(jsonNav);
-    serverOut<<"\",\n\"menu\":";
-    jsonNav.doOutput();
-    serverOut<<"\n}";
-    jsonEnd();
-  });
-
-  server.begin();
-  Serial.println("HTTP server started");
-  Serial.println("Serving ArduinoMenu example.");
-  #ifdef MENU_DEBUG
-    server.serveStatic("/", SPIFFS, "/","max-age=30");
-  #else
-    server.serveStatic("/", SPIFFS, "/","max-age=31536000");
-  #endif
-}
-
-void loop(void){
-  wsOut.response.remove(0);//clear websocket json buffer
-  webSocket.loop();
-  server.handleClient();
-  delay(1);
-}
diff --git a/examples/esp8266/EscControl/EscControl/data/1.5/bootstrap.xslt b/examples/esp8266/EscControl/EscControl/data/1.5/bootstrap.xslt
deleted file mode 100644
index f02ff178..00000000
--- a/examples/esp8266/EscControl/EscControl/data/1.5/bootstrap.xslt
+++ /dev/null
@@ -1,307 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-	xmlns:dyn="http://exslt.org/dynamic">
-
-  <!-- result of the last request -->
-  <xsl:template match="output">
-    <div id="outDlg" class="modal" tabindex="-1" role="dialog">
-      <div class="modal-dialog" role="document">
-        <div class="modal-content">
-          <div class="modal-header">
-            <h3 class="modal-title">Arduino&lt;Web&gt;Menu </h3>
-            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-              <span aria-hidden="true"><xsl:text disable-output-escaping="yes">X</xsl:text></span>
-            </button>
-          </div>
-          <div class="modal-body">
-            <p class="out"><xsl:value-of select="." disable-output-escaping="yes"/></p>
-          </div>
-          <div class="modal-footer">
-            <button type="button" class="btn btn-primary" data-dismiss="modal">Ok</button>
-          </div>
-        </div>
-      </div>
-    </div>
-  </xsl:template>
-
-  <xsl:template match="*">
-    <xsl:apply-templates/>
-  </xsl:template>
-
-  <xsl:template match="sourceURL">
-    <h2 class="sourceURL"><xsl:value-of select="../@host"/></h2>
-  </xsl:template>
-
-  <xsl:template match="menuLib/panel">
-    <div class="aml_panel"><xsl:apply-templates/></div>
-  </xsl:template>
-
-  <xsl:template match="menuLib/panel/tit">
-    <h3><xsl:apply-templates/></h3>
-  </xsl:template>
-
-  <xsl:template match="menu">
-    <ul><xsl:apply-templates/></ul>
-  </xsl:template>
-
-  <xsl:template match="op">
-    <li class="row aml_op btn btn-lg btn-success">
-      <xsl:apply-templates/>
-    </li>
-  </xsl:template>
-
-  <xsl:template match="p[@t='menu']">
-    <xsl:call-template name="linkBtn"/>
-  </xsl:template>
-
-  <xsl:template match="p[@t='mn']" mode="pad">
-    <xsl:call-template name="linkBtn"/>
-  </xsl:template>
-
-  <xsl:template name="linkBtn">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor-or-self::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <xsl:choose>
-      <xsl:when test="@dis='y'">
-        <xsl:apply-templates/>
-      </xsl:when>
-      <xsl:otherwise>
-        <a href="/menu?at={$path}">
-          <xsl:apply-templates/>
-        </a>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-
-  <xsl:template match="op[ob/p/@t='prompt']|op[ob/p/@t='mn']">
-    <xsl:choose>
-      <xsl:when test="@dis='y'">
-        <li class="row aml_op btn btn-lg btn-disabled">
-          <xsl:call-template name="linkBtn"/>
-        </li>
-      </xsl:when>
-      <xsl:otherwise>
-        <li class="row aml_op btn btn-lg btn-success linkBtn">
-          <xsl:call-template name="linkBtn"/>
-        </li>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-
-  <xsl:template match="op[ob/p/@t='prompt']|op[ob/p/@t='mn']" mode="pad">
-    <div class="padOp"><xsl:call-template name="linkBtn"/></div>
-  </xsl:template>
-
-  <xsl:template match="op[@pad='y']">
-    <li class="row aml_op btn btn-lg btn-success">
-      <xsl:apply-templates mode="pad"/>
-    </li>
-  </xsl:template>
-
-  <!-- toggle field -->
-  <xsl:template match="tog">
-    <xsl:apply-templates select="node/value" mode="btns"/>
-  </xsl:template>
-
-  <!-- toggle field -->
-  <xsl:template match="tog" mode="pad">
-    <xsl:apply-templates select="node/value" mode="btns"/>
-  </xsl:template>
-
-  <xsl:template match="fld" mode="pad">
-    <xsl:apply-templates select="."/>
-  </xsl:template>
-
-  <!-- toggle option -->
-  <xsl:template match="node/value" mode="btns">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <a class="aml_btn btn btn-md btn-success" data-grp="{$path}" data-src="{$path}/{position()-1}" href="/menu?at={$path}/{position()-1}">
-      <xsl:apply-templates/>
-    </a>
-  </xsl:template>
-
-  <!-- toggle current option -->
-  <xsl:template match="node/value[@selected]" mode="btns">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <a class="aml_btn btn btn-md btn-primary" data-grp="{$path}" data-src="{$path}/{position()-1}" href="/menu?at={$path}/{position()-1}">
-      <xsl:apply-templates/>
-    </a>
-  </xsl:template>
-
-  <!-- ignorered stuff -->
-  <xsl:template name="ignore" match="cur|fv"/>
-  <xsl:template name="ignorePad" match="cur|fv" mode="pad"/>
-
-  <!-- <xsl:template match="fld[../p[@t='f']]">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <xsl:element name="input">
-      <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="type">text</xsl:attribute>
-      <xsl:attribute name="class">slider ledField</xsl:attribute>
-      <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-      <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-      <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-      <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="data-src"><xsl:value-of select="$path"/></xsl:attribute>
-      <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-    </xsl:element>
-  </xsl:template> -->
-
-  <xsl:template match="fld[../u='%']">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <xsl:element name="input">
-      <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="type">text</xsl:attribute>
-      <xsl:attribute name="class">slider ledField</xsl:attribute>
-      <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-      <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-      <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-      <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="data-src"><xsl:value-of select="$path"/></xsl:attribute>
-      <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-    </xsl:element>
-  </xsl:template>
-
-  <xsl:template match="fld">
-    <xsl:call-template name="fld">
-      <xsl:with-param name="at">
-        <xsl:value-of select="ancestor::*/@r"/>
-        <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-      </xsl:with-param>
-      <xsl:with-param name="type"><xsl:value-of select="../p/@t"/></xsl:with-param>
-    </xsl:call-template>
-  </xsl:template>
-
-  <xsl:template name="fld">
-    <xsl:param name="at"/>
-    <xsl:param name="type"/>
-    <xsl:variable name="ln">
-      <xsl:choose>
-        <xsl:when test="@t>0">
-          <xsl:value-of select="(@h - @l) div @t"/>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:value-of select="(@h - @l) div @s"/>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:variable>
-    <xsl:variable name="szBase">
-      <xsl:choose>
-        <xsl:when test="@h&lt;10 and @l&gt;-10">1</xsl:when>
-        <xsl:when test="@h&lt;100 and @l&gt;-100">2</xsl:when>
-        <xsl:when test="@h&lt;1000 and @l&gt;-1000">3</xsl:when>
-        <xsl:when test="@h&lt;10000 and @l&gt;-10000">4</xsl:when>
-        <xsl:otherwise>8</xsl:otherwise>
-      </xsl:choose>
-    </xsl:variable>
-    <xsl:variable name="sz">
-      <xsl:choose>
-        <xsl:when test="$type='f' and (@s&lt;1 or @t&lt;0)"><xsl:value-of select="$szBase+3"/></xsl:when>
-        <xsl:when test="@l&lt;0"><xsl:value-of select="$szBase+1"/></xsl:when>
-        <xsl:otherwise><xsl:value-of select="$szBase"/></xsl:otherwise>
-      </xsl:choose>
-    </xsl:variable>
-    <xsl:choose>
-      <xsl:when test="$ln>=10000 and $ln&lt;=1000"><!-- disabled in pactice, with a large value -->
-        <xsl:element name="input">
-          <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="type">text</xsl:attribute>
-          <xsl:attribute name="class">slider ledField</xsl:attribute>
-          <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-          <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-          <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-          <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-          <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-          <!-- <xsl:attribute name="data-src"><xsl:value-of select="$path"/></xsl:attribute> -->
-          <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-        </xsl:element>
-        <!-- some fancy slider.. not working yet -->
-        <!-- <xsl:element name="input">
-          <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="type">text</xsl:attribute>
-          <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-          <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-          <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-          <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-        </xsl:element> -->
-        <!-- standard slider -->
-        <!-- <xsl:element name="input">
-          <xsl:copy-of select="node/@*"/>
-          <xsl:copy-of select="../../p/@i"/>
-          <xsl:attribute name="class">menu-range-fld</xsl:attribute>
-          <xsl:attribute name="type">range</xsl:attribute>
-          <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-          <xsl:attribute name="data-src"><xsl:value-of select="$at"/></xsl:attribute>
-          <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-        </xsl:element> -->
-      </xsl:when>
-      <xsl:otherwise>
-      <xsl:element name="input">
-          <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="type">text</xsl:attribute>
-          <xsl:attribute name="size"><xsl:value-of select="$sz"/></xsl:attribute>
-          <xsl:if test="$sz&lt;8">
-            <xsl:attribute name="maxlength"><xsl:value-of select="$sz"/></xsl:attribute>
-          </xsl:if>
-          <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-          <xsl:attribute name="class">form-control</xsl:attribute>
-          <xsl:attribute name="data-src"><xsl:value-of select="$at"/></xsl:attribute>
-          <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-        </xsl:element>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-
-  <xsl:template match="select|choose">
-    <xsl:apply-templates select="node"/>
-  </xsl:template>
-
-  <xsl:template match="node">
-    <xsl:element name="select">
-      <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../../p/@i"/></xsl:attribute>
-      <xsl:attribute name="class">form-control</xsl:attribute>
-      <xsl:attribute name="data-src"><xsl:value-of select="../../../../@r"/>/<xsl:value-of select="../../../@i"/></xsl:attribute>
-      <xsl:attribute name="onchange">window.location.href='/menu?at='+getAttribute('data-src')+'/'+selectedIndex</xsl:attribute>
-      <xsl:apply-templates/>
-    </xsl:element>
-  </xsl:template>
-
-  <xsl:template match="node/value">
-    <xsl:element name="option">
-      <xsl:copy-of select="@*"/>
-      <xsl:apply-templates/>
-    </xsl:element>
-  </xsl:template>
-
-  <xsl:template match="fv[../p[@t='textField']]">
-    <xsl:element name="input">
-    <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../p/@i"/></xsl:attribute>
-    <xsl:attribute name="value"><xsl:value-of select="."/></xsl:attribute>
-    <xsl:attribute name="class">form-control</xsl:attribute>
-    <xsl:attribute name="data-src"><xsl:value-of select="../../../@r"/>/<xsl:value-of select="../../@i"/></xsl:attribute>
-    <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-    </xsl:element>
-  </xsl:template>
-
-</xsl:stylesheet>
diff --git a/examples/esp8266/EscControl/EscControl/data/1.5/device.xslt b/examples/esp8266/EscControl/EscControl/data/1.5/device.xslt
deleted file mode 100644
index 479057a7..00000000
--- a/examples/esp8266/EscControl/EscControl/data/1.5/device.xslt
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
-  <!-- <xsl:output method="html" encoding="utf-8" indent="yes" /> -->
-
-  <xsl:include href="menu.xslt"/>
-  <xsl:include href="bootstrap.xslt"/>
-
-  <!-- put here device specifics translations, if any ////////////////////// -->
-
-</xsl:stylesheet>
diff --git a/examples/esp8266/EscControl/EscControl/data/1.5/index.html b/examples/esp8266/EscControl/EscControl/data/1.5/index.html
deleted file mode 100644
index 3b2cbd0a..00000000
--- a/examples/esp8266/EscControl/EscControl/data/1.5/index.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head profile="http://www.w3.org/2005/10/profile">
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
-  <meta name="description" content="ArduinoMenu Example IOT/OTA for ESP8266">
-  <meta name="author" content="Rui Azevedo <ruihfazevedo@gmail.com> (www.r-site.net)">
-  <title>ArduinoMenu library OTA</title>
-  <link rel="icon" type="image/png" href="/logo.png">
-  <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha256-/SIrNqv8h6QGKDuNoLGA4iret+kyesCkHGzVUUV0shc=" crossorigin="anonymous"></script>
-  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
-  <!--[if lt IE 9]>
-    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
-    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
-  <![endif]-->
-  <!--link rel="stylesheet" type="text/css" href="/r-site.css"-->
-  <link rel="stylesheet" type="text/css" href="menu.css">
-  <script type="text/javascript" src="r-site.js" ></script>
-</head>
-<body class="ArduinoMenu">
-  <div class="site-wrapper">
-
-    <div class="site-wrapper-inner">
-
-      <div class="cover-container">
-
-        <div class="masthead clearfix">
-          <div class="inner">
-            <h3 class="masthead-brand">ArduinoMenu library</h3>
-            <nav>
-              <ul class="nav masthead-nav">
-                <li class="active"><a href="/" id="start">Home</a></li>
-                <li><a href="/menu?at=/" id="menu">Menu</a></li>
-                <li><a href="https://github.com/neu-rah/ArduinoMenu">Repo</a></li>
-                <!--li><a href="#">Features</a></li-->
-                <li><a href="http://www.r-site.net/site/struct.asp?at=//menu[@id=%27main%27]/*[5]">Contact</a></li>
-              </ul>
-            </nav>
-          </div>
-        </div>
-
-        <div class="inner cover">
-          <h2><img src="/img/logo.png" height="48px"/>on ESP8266</h1>
-          <p>You can customize this page, it is static.</p>
-            <a href="/menu" class="btn btn-lg">Full menu</a>
-        </div>
-        <hr/>
-        <div class="mastfoot">
-          <div class="inner">
-            <p>ArduinoMenu library <a href="https://github.com/neu-rah/ArduinoMenu">https://github.com/neu-rah/ArduinoMenu</a>.</p>
-          </div>
-        </div>
-
-      </div>
-
-    </div>
-
-  </div>
-
-</body></html>
diff --git a/examples/esp8266/EscControl/EscControl/data/1.5/menu.css b/examples/esp8266/EscControl/EscControl/data/1.5/menu.css
deleted file mode 100644
index b5b9b91a..00000000
--- a/examples/esp8266/EscControl/EscControl/data/1.5/menu.css
+++ /dev/null
@@ -1,302 +0,0 @@
-html,
-body {
-  height: 100%;
-  background-color: #1d80e2;
-}
-body {
-  color: #fff;
-  text-align: center;
-  text-shadow: 0 1px 3px rgba(0,0,0,.5);
-  font-size: 18px;
-}
-
-#outDlg .modal-content, .upForm {
-  background-color: #888 !important;
-  padding:1em;
-}
-
-/* .masthead {
-  background-image: url(nav-bg.jpg);
-  background-size: cover;
-  background-position: center;
-} */
-
-nav {
-  background-color: #333;
-}
-
-a {
-  text-decoration: none !important;
-}
-
-input, select {
-  width: auto;
-  color: yellow;
-  background-color: transparent;
-  /* border: none; */
-}
-
-input[@type="uint32_t"] {
-  text-align: right;
-}
-
-/* Links */
-a,
-a:focus,
-a:hover {
-  color: #fff;
-}
-
-/* .asPad {background-color: gray;} */
-.pad-item {display: inline-block !important;}
-
-.form-control {
-  width:auto;
-  display:inline-block;
-}
-
-.aml_op.btn {width:100%;}
-
-.actionBtn {
-  display:inline-block;
-  padding:1em;
-  background-color: #0ba6a4;
-  color: lime;
-  border: solid 1px lime;
-  border-radius: 3px;
-  text-align: right;
-}
-
-/* Custom default button */
-.btn-default,
-.btn-default:hover,
-.btn-default:focus {
-  color: #333;
-  text-shadow: none; /* Prevent inheritance from `body` */
-  background-color: #fff;
-  border: 1px solid #fff;
-}
-
-input[type=range] {
-  display:inline-block !important;
-  width:auto !important;
-  background-color:#000800;
-}
-
-/*
- * Base structure
- */
-
-select {color: black;}
-
-/* Extra markup and styles for table-esque vertical and horizontal centering */
-.site-wrapper {
-  display: table;
-  width: 100%;
-  height: 100%; /* For at least Firefox */
-  min-height: 100%;
-  -webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-          box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-}
-.site-wrapper-inner {
-  display: table-cell;
-  vertical-align: top;
-}
-.cover-container {
-  margin-right: auto;
-  margin-left: auto;
-}
-
-/* Padding for spacing */
-/* .inner {
-  padding: 30px;
-} */
-
-
-/*
- * Header
- */
-.masthead{
-	background-color: #1d80e2;
-	height:150px;
-  overflow:hidden;
-  z-index:100;
-}
-/* .masthead-brand {
-  margin-top: 0px !important;
-} */
-.masthead .wrap{
-	-webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-    box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-	height:200px;
-}
-
-.masthead .inner{
-	/* padding:0 20px 0 60px; */
-}
-
-.masthead-brand {
-  margin-top: 0px;
-  padding-top: 0.5em;
-  margin-bottom: 0em;
-}
-
-ul {
-  list-style-type: none;
-}
-
-.masthead-nav > li {
-  display: inline-block;
-}
-.masthead-nav > li + li {
-  margin-left: 0.5em;
-}
-.masthead-nav > li > a {
-  padding-right: 0;
-  padding-left: 0;
-  font-size: 16px;
-  font-weight: bold;
-  color: #fff; /* IE8 proofing */
-  color: rgba(255,255,255,.75);
-  border-bottom: 2px solid transparent;
-}
-.masthead-nav > li > a:hover,
-.masthead-nav > li > a:focus {
-  background-color: transparent;
-  border-bottom-color: #a9a9a9;
-  border-bottom-color: rgba(255,255,255,.25);
-}
-.masthead-nav > .active > a,
-.masthead-nav > .active > a:hover,
-.masthead-nav > .active > a:focus {
-  color: #fff;
-  border-bottom-color: #fff;
-}
-
-@media (min-width: 768px) {
-  .masthead{
-  	height:100px;
-  }
-  .masthead-brand {
-    float: left;
-  }
-  .masthead-nav {
-  margin-top: 1em;
-    float: right;
-  }
-}
-
-/*
- * Cover
- */
-
-.cover .btn-lg {
-  /* padding: 10px 20px; */
-  font-weight: bold;
-}
-
-.cover .btn-lg.linkBtn>a {
-  padding: 10px 20px;
-}
-
-/*
- * Footer
- */
-
-.mastfoot {
-  font-size: 0.6em;
-  color: #999; /* IE8 proofing */
-  color: rgba(255,255,255,.5);
-  /* z-index: -1; */
-}
-
-
-/*
- * Affix and center
- */
-
-@media (min-width: 768px) {
-  /* Pull out the header and footer */
-  .masthead {
-    position: fixed;
-    top: 0;
-	  left: 0;
-  }
-  .mastfoot {
-    position: fixed;
-    bottom: 0;
-  }
-  /* Start the vertical centering */
-  .site-wrapper-inner {
-    vertical-align: middle;
-  }
-  /* Handle the widths */
-  .masthead,
-  .mastfoot,
-  .cover-container {
-    width: 100%; /* Must be percentage or pixels for horizontal alignment */
-  }
-  .cover-container {
-    width: 700px;
-  }
-  .cover {
-    padding: 100px 1em 1em 1em !important;
-  }
-
-}
-
-@media (min-width: 992px) {
-  .masterhead {
-    padding: 1em;
-  }
-  .masthead .inner{
-	   margin: 0 auto;
-  }
-  .masthead .inner,
-  .mastfoot,
-  .cover-container {
-    width: 700px;
-  }
-  .cover {
-    padding: 100px 1em 1em 1em !important;
-  }
-}
-
-.btn-active {
-  color: #fff;
-  background-color: #333;
-  border-color: #d58512;
-}
-
-.btn-disabled {
-  color: #fff;
-  background-color: #696969;
-  border-color: #4cae4c;
-}
-
-.slider {
-  margin-right:1em;
-  margin-left: 1em;
-}
-
-.slider-selection {
-	background: #BABABA;
-}
-
-.slider.slider-horizontal {
-  width:20% !important;
-}
-
-.aml_op .del {
-  color:red;
-}
-
-div.padOp {display:inline-block;}
-
-li.linkBtn {padding:0;}
-li.linkBtn>a {display:block;margin:0;}
-
-.btn-space {
-  padding-left:0.5em;
-  padding-right:0.5em;
-}
diff --git a/examples/esp8266/EscControl/EscControl/data/1.5/menu.xslt b/examples/esp8266/EscControl/EscControl/data/1.5/menu.xslt
deleted file mode 100644
index 17884ad6..00000000
--- a/examples/esp8266/EscControl/EscControl/data/1.5/menu.xslt
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-	xmlns:dyn="http://r-site.net"
-	xmlns:msxsl="urn:schemas-microsoft-com:xslt"
-	extension-element-prefixes="dyn msxsl">
-
-  <!-- you can host aux files on external server
-    if it is the case set this variable to the server address:port
-    this is usefull for develop/debug
-    to use external server the browser must be intructed to accept cross domain files
-  -->
-  <!-- <xsl:variable name="auxFilesSrc"></xsl:variable> -->
-  <xsl:variable name="auxFilesSrc">
-    <xsl:choose>
-      <xsl:when test="/menuLib/@debug='yes'">http://neurux:8080/</xsl:when>
-      <xsl:otherwise></xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-
-  <xsl:template match="/">
-    <html>
-      <head>
-        <meta charset="utf-8"/>
-        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
-        <meta name="viewport" content="width=device-width, initial-scale=1"/>
-        <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
-        <meta name="description" content="ArduinoMenu Library auto generated web menu"/>
-        <meta name="author" content="Rui Azevedo ruihfazevedo@gmail.com (https://github.com/neu-rah)"/>
-        <title>ArduinoMenu&lt;web&gt;</title>
-        <!-- <script src="{$auxFilesSrc}/jquery-3.3.1.min.js"></script> -->
-        <script
-          src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
-          integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="
-          crossorigin="anonymous"></script>
-
-        <!-- Latest compiled and minified CSS -->
-        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"/>
-
-        <!-- Optional theme -->
-        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"/>
-
-        <!-- Latest compiled and minified JavaScript -->
-        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-
-        <!-- <link href="{$auxFilesSrc}/bootstrap.min.css" rel="stylesheet"/>
-        <script src="{$auxFilesSrc}/bootstrap.min.js"></script> -->
-        <link href="{$auxFilesSrc}/bootstrap-slider.min.css" rel="stylesheet"/>
-        <script src="{$auxFilesSrc}/bootstrap-slider.min.js"></script>
-        <link rel="stylesheet" type="text/css" href="{$auxFilesSrc}/{/menuLib/sourceURL/@ver}menu.css"/>
-        <script src="{$auxFilesSrc}/{/menuLib/sourceURL/@ver}r-site.js"></script>
-        <link rel="icon" type="image/png" href="/img/icon.png"/>
-      </head>
-      <body class="ArduinoMenu">
-        <div class="site-wrapper">
-          <div class="site-wrapper-inner">
-            <div class="cover-container">
-              <div class="masthead clearfix">
-                <div class="wrap">
-                <div class="inner">
-                  <h1 class="masthead-brand">
-                    <a href="http://r-site.net/" target="_blank"><img src="/img/logo.png" height="72px" alt="r-site.net"/></a>
-        				  </h1>
-                          <nav>
-                            <ul class="nav masthead-nav">
-                              <li><a href="/" id="start">Home</a></li>
-                              <li class="active"><a href="/menu?at=/" id="menu">Menu</a></li>
-                              <li><a href="https://github.com/neu-rah/ArduinoMenu" id="repo" target="_blank">Repo</a></li>
-                              <li><a href="http://www.r-site.net/site/struct.asp?at=//menu[@id=%27main%27]/*[5]" id="contact" target="_blank">Contact</a></li>
-                            </ul>
-                          </nav>
-                </div>
-                </div>
-              </div>
-              <div class="inner cover">
-                <xsl:apply-templates/>
-              </div>
-
-              <div class="mastfoot">
-                <div class="inner">
-                  <p>ArduinoMenu library <a href="https://github.com/neu-rah/ArduinoMenu">https://github.com/neu-rah/ArduinoMenu</a>.</p>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </body>
-    </html>
-  </xsl:template>
-
-</xsl:stylesheet>
diff --git a/examples/esp8266/EscControl/EscControl/data/1.5/r-site.js b/examples/esp8266/EscControl/EscControl/data/1.5/r-site.js
deleted file mode 100644
index 9e948659..00000000
--- a/examples/esp8266/EscControl/EscControl/data/1.5/r-site.js
+++ /dev/null
@@ -1,176 +0,0 @@
-// wsSrc = sourceURL;
-wsSrc=window.location.hostname;
-var connection = {};
-
-// alert("r-site.js loaded!");
-var lastResult=null;
-var previousResult=null;
-
-function connectWS() {
-  console.log("ws://" + wsSrc + ":81/", ["arduino"]);
-  connection = new WebSocket("ws://" + wsSrc + ":81/", ["arduino"]);
-  connection.onopen = init;
-  connection.onerror = function(e) {console.log("WebSocket Error ", e)};
-  connection.onmessage = function(e) {
-    try {
-      console.log(JSON.parse(e.data));//just for checking it
-    } catch(err) {
-      console.log("NO JSON!",e.data);
-    }
-    eval("lastResult="+e.data);
-    //updatePage();
-  };
-  return connection.readyState;
-}
-
-function updatePage() {
-  if (lastResult) mkPath(lastResult);//add path info
-  if (lastResult==previousResult) return;
-  if (previousResult&&lastResult.menu.title.prompt===previousResult.menu.title.prompt)
-      walkStates(lastResult.menu,previousResult.menu);
-  previousResult=lastResult;
-}
-
-function refreshBtn(_,o) {
-  var p=$(o).attr("data-src");
-  var g=$(o).attr("data-grp");
-  var nv=jpath(g,lastResult.menu);
-  if (nv.value==$(o).text())
-    console.log(p,g,nv);
-}
-
-//get a single value out a menu state page by path
-//it matches the page postion and selects requested item
-//so path is absolute
-function jpath(p,m) {
-  if (m.path!=p.slice(0,m.path.length)) return;
-  var ps=p.slice(m.path.length).split("/").slice(1);
-  return _jpath(m,ps);
-  function _jpath(m,o) {
-    var i=(m.pad||m.items)
-    if (!i&&o.length>0) return;
-    return (o.length&&i)?_jpath(i[o[0]],o.slice(1)):m
-  }
-}
-
-//traverses previous and last state and
-//update controls of changed values
-function walkStates(i,j) {
-  if(!(i&&j)) return;
-  // console.log("walking states...");
-  if (i.path!=j.path) return;
-  // console.log("path",i.path);
-  if (i.field&&j.field&&i.field!=j.field) {//numeric field!
-    var target=$("[data-src='"+i.path+"'");
-    if (target.length) {
-      console.log("setting new field",i.path,i.field,target);
-      if (target.hasClass("slider")) target.slider("setValue",i.field);
-      else target.val(i.field);
-    }
-  } if (i.options&&j.options&&i.value!=j.value) {//enumerated field
-    var nvi=i.options.indexOf(i.value);
-    console.log("looking for",i.path);
-    var target=$("[data-src='"+i.path+"/"+nvi+"']");
-    if (target.length) {
-      console.log("clicking on button");
-      target.click();
-    } else {
-      target=$("select[data-src='"+i.path+"']");
-      if (target.length) {
-        console.log("changing selection",i.path,i.select);
-        target.val(i.select);
-      }
-
-    }
-  }
-  if (typeof i[Symbol.iterator] === 'function'&&typeof j[Symbol.iterator] === 'function')
-    for(var n=0;n<i.length;n++)
-      walkStates(i[n],j[n]);
-  if(i.pad) walkStates(i.pad,j.pad)
-  if(i.items) walkStates(i.items,j.items)
-}
-
-function mkPath(m) {
-  if (m.menu) _mkPath(m.menu.items,m.menu.path||"")
-  function _mkPath(i,path) {
-    // console.log("_mkPath:",path,i);
-    if (i.idx) i.path=path+"/"+i.idx;
-    if (typeof i[Symbol.iterator] === 'function')
-      for(n of i)
-        _mkPath(n,i.path||path);
-    if(i.pad) _mkPath(i.pad,i.path||path)
-  }
-}
-
-function menu(o,cnt) {
-  if(connection.readyState!=1) {//not connected (yet)?
-    console.log("not connected yet...")
-    if (connection.readyState==3) {//disconnected?
-      console.log("connecting websocket");
-      connectWS();
-    }
-    setTimeout(function() {//check latter...
-      console.log("checking websocket connetion");
-      if (connection.readyState!=1&&cnt>5) {//give up?
-        alert("websocket disconnected, please refresh page");//TODO: put mutilang here
-        return;
-      } else menu(o,cnt?cnt+1:0);
-    },500);
-    return;
-  }
-  console.log("send ws",o);
-  return connection.send(o);
-}
-
-function updateField(e) {
-  return updateField_(e.target)
-}
-
-function updateField_(e) {
-  var n = $(e).attr("data-src") + "/" + e.value + String.fromCharCode(255);
-  menu(n);
-}
-
-function updateLink(e) {
-  return updateLink_(e.target)
-}
-
-function updateLink_(e) {
-  var n = $(e),
-    o = n.attr("data-grp"),
-    t = n.attr("data-src");
-  // console.log("removing selections");
-  $("a[data-grp='" + o + "']").removeClass("btn-primary btn-success");
-  // console.log("adding selection to", e);
-  n.addClass("btn-primary");
-  // console.log("sending: " + t);
-  menu(t);
-  // connection.send(t)
-}
-
-function updateSelect(e) {
-  updateSelect_(e.target)
-}
-
-function updateSelect_(e) {
-  var n = $(e).attr("data-src") + "/" + e.selectedIndex;
-  // console.log("sending: " + n);
-  menu(n);
-  // connection.send(n);
-}
-
-function init() {
-  console.log("menu websocket server connected.");
-  console.log("r-site menu page script starting.");
-  activePanel = $(".aml_panel");
-  $(".aml_op>input").removeAttr("onchange").off("change").on("change", updateField);
-  $(".aml_op>select").removeAttr("onchange").off("change").on("change", updateSelect);
-  $("a.aml_btn").removeAttr("href").off("click").on("click", updateLink);
-  // $(".aml_op input.ledField").removeAttr("onchange").off("change").on("change", logField);
-}
-$(function() {
-  // console.log("ready!");
-  connectWS();
-  $("p.out").text() && $("#outDlg").modal();
-  jQuery().slider && $(".slider").slider({formatter: function(e) {return e + "%"}});
-});
diff --git a/examples/esp8266/EscControl/EscControl/data/bootstrap-slider.min.css b/examples/esp8266/EscControl/EscControl/data/bootstrap-slider.min.css
deleted file mode 100644
index c0234bfd..00000000
--- a/examples/esp8266/EscControl/EscControl/data/bootstrap-slider.min.css
+++ /dev/null
@@ -1,41 +0,0 @@
-/*! =======================================================
-                      VERSION  10.0.0
-========================================================= */
-/*! =========================================================
- * bootstrap-slider.js
- *
- * Maintainers:
- *		Kyle Kemp
- *			- Twitter: @seiyria
- *			- Github:  seiyria
- *		Rohit Kalkur
- *			- Twitter: @Rovolutionary
- *			- Github:  rovolution
- *
- * =========================================================
-  *
- * bootstrap-slider is released under the MIT License
- * Copyright (c) 2017 Kyle Kemp, Rohit Kalkur, and contributors
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * ========================================================= */.slider{display:inline-block;vertical-align:middle;position:relative}.slider.slider-horizontal{width:210px;height:20px}.slider.slider-horizontal .slider-track{height:10px;width:100%;margin-top:-5px;top:50%;left:0}.slider.slider-horizontal .slider-selection,.slider.slider-horizontal .slider-track-low,.slider.slider-horizontal .slider-track-high{height:100%;top:0;bottom:0}.slider.slider-horizontal .slider-tick,.slider.slider-horizontal .slider-handle{margin-left:-10px}.slider.slider-horizontal .slider-tick.triangle,.slider.slider-horizontal .slider-handle.triangle{position:relative;top:50%;-ms-transform:translateY(-50%);transform:translateY(-50%);border-width:0 10px 10px 10px;width:0;height:0;border-bottom-color:#2e6da4;margin-top:0}.slider.slider-horizontal .slider-tick-container{white-space:nowrap;position:absolute;top:0;left:0;width:100%}.slider.slider-horizontal .slider-tick-label-container{white-space:nowrap;margin-top:20px}.slider.slider-horizontal .slider-tick-label-container .slider-tick-label{padding-top:4px;display:inline-block;text-align:center}.slider.slider-horizontal .tooltip{-ms-transform:translateX(-50%);transform:translateX(-50%)}.slider.slider-horizontal.slider-rtl .slider-track{left:initial;right:0}.slider.slider-horizontal.slider-rtl .slider-tick,.slider.slider-horizontal.slider-rtl .slider-handle{margin-left:initial;margin-right:-10px}.slider.slider-horizontal.slider-rtl .slider-tick-container{left:initial;right:0}.slider.slider-horizontal.slider-rtl .tooltip{-ms-transform:translateX(50%);transform:translateX(50%)}.slider.slider-vertical{height:210px;width:20px}.slider.slider-vertical .slider-track{width:10px;height:100%;left:25%;top:0}.slider.slider-vertical .slider-selection{width:100%;left:0;top:0;bottom:0}.slider.slider-vertical .slider-track-low,.slider.slider-vertical .slider-track-high{width:100%;left:0;right:0}.slider.slider-vertical .slider-tick,.slider.slider-vertical .slider-handle{margin-top:-10px}.slider.slider-vertical .slider-tick.triangle,.slider.slider-vertical .slider-handle.triangle{border-width:10px 0 10px 10px;width:1px;height:1px;border-left-color:#2e6da4;border-right-color:#2e6da4;margin-left:0;margin-right:0}.slider.slider-vertical .slider-tick-label-container{white-space:nowrap}.slider.slider-vertical .slider-tick-label-container .slider-tick-label{padding-left:4px}.slider.slider-vertical .tooltip{-ms-transform:translateY(-50%);transform:translateY(-50%)}.slider.slider-vertical.slider-rtl .slider-track{left:initial;right:25%}.slider.slider-vertical.slider-rtl .slider-selection{left:initial;right:0}.slider.slider-vertical.slider-rtl .slider-tick.triangle,.slider.slider-vertical.slider-rtl .slider-handle.triangle{border-width:10px 10px 10px 0}.slider.slider-vertical.slider-rtl .slider-tick-label-container .slider-tick-label{padding-left:initial;padding-right:4px}.slider.slider-disabled .slider-handle{background-image:-webkit-linear-gradient(top,#dfdfdf 0,#bebebe 100%);background-image:-o-linear-gradient(top,#dfdfdf 0,#bebebe 100%);background-image:linear-gradient(to bottom,#dfdfdf 0,#bebebe 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdfdfdf',endColorstr='#ffbebebe',GradientType=0)}.slider.slider-disabled .slider-track{background-image:-webkit-linear-gradient(top,#e5e5e5 0,#e9e9e9 100%);background-image:-o-linear-gradient(top,#e5e5e5 0,#e9e9e9 100%);background-image:linear-gradient(to bottom,#e5e5e5 0,#e9e9e9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe5e5e5',endColorstr='#ffe9e9e9',GradientType=0);cursor:not-allowed}.slider input{display:none}.slider .tooltip.top{margin-top:-36px}.slider .tooltip-inner{white-space:nowrap;max-width:none}.slider .hide{display:none}.slider-track{position:absolute;cursor:pointer;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#f9f9f9 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#f9f9f9 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#f9f9f9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);border-radius:4px}.slider-selection{position:absolute;background-image:-webkit-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#f9f9f9 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:4px}.slider-selection.tick-slider-selection{background-image:-webkit-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:-o-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:linear-gradient(to bottom,#8ac1ef 0,#82b3de 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8ac1ef',endColorstr='#ff82b3de',GradientType=0)}.slider-track-low,.slider-track-high{position:absolute;background:transparent;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:4px}.slider-handle{position:absolute;top:0;width:20px;height:20px;background-color:#337ab7;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7',endColorstr='#ff2e6da4',GradientType=0);filter:none;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);border:0 solid transparent}.slider-handle.round{border-radius:50%}.slider-handle.triangle{background:transparent none}.slider-handle.custom{background:transparent none}.slider-handle.custom::before{line-height:20px;font-size:20px;content:'\2605';color:#726204}.slider-tick{position:absolute;width:20px;height:20px;background-image:-webkit-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#f9f9f9 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;filter:none;opacity:.8;border:0 solid transparent}.slider-tick.round{border-radius:50%}.slider-tick.triangle{background:transparent none}.slider-tick.custom{background:transparent none}.slider-tick.custom::before{line-height:20px;font-size:20px;content:'\2605';color:#726204}.slider-tick.in-selection{background-image:-webkit-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:-o-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:linear-gradient(to bottom,#8ac1ef 0,#82b3de 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8ac1ef',endColorstr='#ff82b3de',GradientType=0);opacity:1}
diff --git a/examples/esp8266/EscControl/EscControl/data/bootstrap-slider.min.js b/examples/esp8266/EscControl/EscControl/data/bootstrap-slider.min.js
deleted file mode 100644
index bd11ca85..00000000
--- a/examples/esp8266/EscControl/EscControl/data/bootstrap-slider.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*! =======================================================
-                      VERSION  10.0.0
-========================================================= */
-"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},windowIsDefined="object"===("undefined"==typeof window?"undefined":_typeof(window));!function(a){if("function"==typeof define&&define.amd)define(["jquery"],a);else if("object"===("undefined"==typeof module?"undefined":_typeof(module))&&module.exports){var b;try{b=require("jquery")}catch(c){b=null}module.exports=a(b)}else window&&(window.Slider=a(window.jQuery))}(function(a){var b="slider",c="bootstrapSlider";windowIsDefined&&!window.console&&(window.console={}),windowIsDefined&&!window.console.log&&(window.console.log=function(){}),windowIsDefined&&!window.console.warn&&(window.console.warn=function(){});var d;return function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l&&l!==k)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}var m=this.map(function(){var d=a.data(this,b);return d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d)),a(this)});return!m||m.length>1?m:m[0]}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;c(a)}(a),function(a){function e(b,c){function d(a,b){var c="data-slider-"+b.replace(/_/g,"-"),d=a.getAttribute(c);try{return JSON.parse(d)}catch(e){return d}}this._state={value:null,enabled:null,offset:null,size:null,percentage:null,inDrag:!1,over:!1},this.ticksCallbackMap={},this.handleCallbackMap={},"string"==typeof b?this.element=document.querySelector(b):b instanceof HTMLElement&&(this.element=b),c=c?c:{};for(var e=Object.keys(this.defaultOptions),f=0;f<e.length;f++){var h=e[f],i=c[h];i="undefined"!=typeof i?i:d(this.element,h),i=null!==i?i:this.defaultOptions[h],this.options||(this.options={}),this.options[h]=i}"auto"===this.options.rtl&&(this.options.rtl="rtl"===window.getComputedStyle(this.element).direction),"vertical"!==this.options.orientation||"top"!==this.options.tooltip_position&&"bottom"!==this.options.tooltip_position?"horizontal"!==this.options.orientation||"left"!==this.options.tooltip_position&&"right"!==this.options.tooltip_position||(this.options.tooltip_position="top"):this.options.rtl?this.options.tooltip_position="left":this.options.tooltip_position="right";var j,k,l,m,n,o=this.element.style.width,p=!1,q=this.element.parentNode;if(this.sliderElem)p=!0;else{this.sliderElem=document.createElement("div"),this.sliderElem.className="slider";var r=document.createElement("div");r.className="slider-track",k=document.createElement("div"),k.className="slider-track-low",j=document.createElement("div"),j.className="slider-selection",l=document.createElement("div"),l.className="slider-track-high",m=document.createElement("div"),m.className="slider-handle min-slider-handle",m.setAttribute("role","slider"),m.setAttribute("aria-valuemin",this.options.min),m.setAttribute("aria-valuemax",this.options.max),n=document.createElement("div"),n.className="slider-handle max-slider-handle",n.setAttribute("role","slider"),n.setAttribute("aria-valuemin",this.options.min),n.setAttribute("aria-valuemax",this.options.max),r.appendChild(k),r.appendChild(j),r.appendChild(l),this.rangeHighlightElements=[];var s=this.options.rangeHighlights;if(Array.isArray(s)&&s.length>0)for(var t=0;t<s.length;t++){var u=document.createElement("div"),v=s[t]["class"]||"";u.className="slider-rangeHighlight slider-selection "+v,this.rangeHighlightElements.push(u),r.appendChild(u)}var w=Array.isArray(this.options.labelledby);if(w&&this.options.labelledby[0]&&m.setAttribute("aria-labelledby",this.options.labelledby[0]),w&&this.options.labelledby[1]&&n.setAttribute("aria-labelledby",this.options.labelledby[1]),!w&&this.options.labelledby&&(m.setAttribute("aria-labelledby",this.options.labelledby),n.setAttribute("aria-labelledby",this.options.labelledby)),this.ticks=[],Array.isArray(this.options.ticks)&&this.options.ticks.length>0){for(this.ticksContainer=document.createElement("div"),this.ticksContainer.className="slider-tick-container",f=0;f<this.options.ticks.length;f++){var x=document.createElement("div");if(x.className="slider-tick",this.options.ticks_tooltip){var y=this._addTickListener(),z=y.addMouseEnter(this,x,f),A=y.addMouseLeave(this,x);this.ticksCallbackMap[f]={mouseEnter:z,mouseLeave:A}}this.ticks.push(x),this.ticksContainer.appendChild(x)}j.className+=" tick-slider-selection"}if(this.tickLabels=[],Array.isArray(this.options.ticks_labels)&&this.options.ticks_labels.length>0)for(this.tickLabelContainer=document.createElement("div"),this.tickLabelContainer.className="slider-tick-label-container",f=0;f<this.options.ticks_labels.length;f++){var B=document.createElement("div"),C=0===this.options.ticks_positions.length,D=this.options.reversed&&C?this.options.ticks_labels.length-(f+1):f;B.className="slider-tick-label",B.innerHTML=this.options.ticks_labels[D],this.tickLabels.push(B),this.tickLabelContainer.appendChild(B)}var E=function(a){var b=document.createElement("div");b.className="tooltip-arrow";var c=document.createElement("div");c.className="tooltip-inner",a.appendChild(b),a.appendChild(c)},F=document.createElement("div");F.className="tooltip tooltip-main",F.setAttribute("role","presentation"),E(F);var G=document.createElement("div");G.className="tooltip tooltip-min",G.setAttribute("role","presentation"),E(G);var H=document.createElement("div");H.className="tooltip tooltip-max",H.setAttribute("role","presentation"),E(H),this.sliderElem.appendChild(r),this.sliderElem.appendChild(F),this.sliderElem.appendChild(G),this.sliderElem.appendChild(H),this.tickLabelContainer&&this.sliderElem.appendChild(this.tickLabelContainer),this.ticksContainer&&this.sliderElem.appendChild(this.ticksContainer),this.sliderElem.appendChild(m),this.sliderElem.appendChild(n),q.insertBefore(this.sliderElem,this.element),this.element.style.display="none"}if(a&&(this.$element=a(this.element),this.$sliderElem=a(this.sliderElem)),this.eventToCallbackMap={},this.sliderElem.id=this.options.id,this.touchCapable="ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,this.touchX=0,this.touchY=0,this.tooltip=this.sliderElem.querySelector(".tooltip-main"),this.tooltipInner=this.tooltip.querySelector(".tooltip-inner"),this.tooltip_min=this.sliderElem.querySelector(".tooltip-min"),this.tooltipInner_min=this.tooltip_min.querySelector(".tooltip-inner"),this.tooltip_max=this.sliderElem.querySelector(".tooltip-max"),this.tooltipInner_max=this.tooltip_max.querySelector(".tooltip-inner"),g[this.options.scale]&&(this.options.scale=g[this.options.scale]),p===!0&&(this._removeClass(this.sliderElem,"slider-horizontal"),this._removeClass(this.sliderElem,"slider-vertical"),this._removeClass(this.sliderElem,"slider-rtl"),this._removeClass(this.tooltip,"hide"),this._removeClass(this.tooltip_min,"hide"),this._removeClass(this.tooltip_max,"hide"),["left","right","top","width","height"].forEach(function(a){this._removeProperty(this.trackLow,a),this._removeProperty(this.trackSelection,a),this._removeProperty(this.trackHigh,a)},this),[this.handle1,this.handle2].forEach(function(a){this._removeProperty(a,"left"),this._removeProperty(a,"right"),this._removeProperty(a,"top")},this),[this.tooltip,this.tooltip_min,this.tooltip_max].forEach(function(a){this._removeProperty(a,"left"),this._removeProperty(a,"right"),this._removeProperty(a,"top"),this._removeClass(a,"right"),this._removeClass(a,"left"),this._removeClass(a,"top")},this)),"vertical"===this.options.orientation?(this._addClass(this.sliderElem,"slider-vertical"),this.stylePos="top",this.mousePos="pageY",this.sizePos="offsetHeight"):(this._addClass(this.sliderElem,"slider-horizontal"),this.sliderElem.style.width=o,this.options.orientation="horizontal",this.options.rtl?this.stylePos="right":this.stylePos="left",this.mousePos="pageX",this.sizePos="offsetWidth"),this.options.rtl&&this._addClass(this.sliderElem,"slider-rtl"),this._setTooltipPosition(),Array.isArray(this.options.ticks)&&this.options.ticks.length>0&&(this.options.max=Math.max.apply(Math,this.options.ticks),this.options.min=Math.min.apply(Math,this.options.ticks)),Array.isArray(this.options.value)?(this.options.range=!0,this._state.value=this.options.value):this.options.range?this._state.value=[this.options.value,this.options.max]:this._state.value=this.options.value,this.trackLow=k||this.trackLow,this.trackSelection=j||this.trackSelection,this.trackHigh=l||this.trackHigh,"none"===this.options.selection?(this._addClass(this.trackLow,"hide"),this._addClass(this.trackSelection,"hide"),this._addClass(this.trackHigh,"hide")):("after"===this.options.selection||"before"===this.options.selection)&&(this._removeClass(this.trackLow,"hide"),this._removeClass(this.trackSelection,"hide"),this._removeClass(this.trackHigh,"hide")),this.handle1=m||this.handle1,this.handle2=n||this.handle2,p===!0)for(this._removeClass(this.handle1,"round triangle"),this._removeClass(this.handle2,"round triangle hide"),f=0;f<this.ticks.length;f++)this._removeClass(this.ticks[f],"round triangle hide");var I=["round","triangle","custom"],J=-1!==I.indexOf(this.options.handle);if(J)for(this._addClass(this.handle1,this.options.handle),this._addClass(this.handle2,this.options.handle),f=0;f<this.ticks.length;f++)this._addClass(this.ticks[f],this.options.handle);if(this._state.offset=this._offset(this.sliderElem),this._state.size=this.sliderElem[this.sizePos],this.setValue(this._state.value),this.handle1Keydown=this._keydown.bind(this,0),this.handle1.addEventListener("keydown",this.handle1Keydown,!1),this.handle2Keydown=this._keydown.bind(this,1),this.handle2.addEventListener("keydown",this.handle2Keydown,!1),this.mousedown=this._mousedown.bind(this),this.touchstart=this._touchstart.bind(this),this.touchmove=this._touchmove.bind(this),this.touchCapable){var K=!1;try{var L=Object.defineProperty({},"passive",{get:function(){K=!0}});window.addEventListener("test",null,L)}catch(M){}var N=K?{passive:!0}:!1;this.sliderElem.addEventListener("touchstart",this.touchstart,N),this.sliderElem.addEventListener("touchmove",this.touchmove,N)}if(this.sliderElem.addEventListener("mousedown",this.mousedown,!1),this.resize=this._resize.bind(this),window.addEventListener("resize",this.resize,!1),"hide"===this.options.tooltip)this._addClass(this.tooltip,"hide"),this._addClass(this.tooltip_min,"hide"),this._addClass(this.tooltip_max,"hide");else if("always"===this.options.tooltip)this._showTooltip(),this._alwaysShowTooltip=!0;else{if(this.showTooltip=this._showTooltip.bind(this),this.hideTooltip=this._hideTooltip.bind(this),this.options.ticks_tooltip){var O=this._addTickListener(),P=O.addMouseEnter(this,this.handle1),Q=O.addMouseLeave(this,this.handle1);this.handleCallbackMap.handle1={mouseEnter:P,mouseLeave:Q},P=O.addMouseEnter(this,this.handle2),Q=O.addMouseLeave(this,this.handle2),this.handleCallbackMap.handle2={mouseEnter:P,mouseLeave:Q}}else this.sliderElem.addEventListener("mouseenter",this.showTooltip,!1),this.sliderElem.addEventListener("mouseleave",this.hideTooltip,!1);this.handle1.addEventListener("focus",this.showTooltip,!1),this.handle1.addEventListener("blur",this.hideTooltip,!1),this.handle2.addEventListener("focus",this.showTooltip,!1),this.handle2.addEventListener("blur",this.hideTooltip,!1)}this.options.enabled?this.enable():this.disable()}var f={formatInvalidInputErrorMsg:function(a){return"Invalid input value '"+a+"' passed in"},callingContextNotSliderInstance:"Calling context element does not have instance of Slider bound to it. Check your code to make sure the JQuery object returned from the call to the slider() initializer is calling the method"},g={linear:{toValue:function(a){var b=a/100*(this.options.max-this.options.min),c=!0;if(this.options.ticks_positions.length>0){for(var d,e,f,g=0,h=1;h<this.options.ticks_positions.length;h++)if(a<=this.options.ticks_positions[h]){d=this.options.ticks[h-1],f=this.options.ticks_positions[h-1],e=this.options.ticks[h],g=this.options.ticks_positions[h];break}var i=(a-f)/(g-f);b=d+i*(e-d),c=!1}var j=c?this.options.min:0,k=j+Math.round(b/this.options.step)*this.options.step;return k<this.options.min?this.options.min:k>this.options.max?this.options.max:k},toPercentage:function(a){if(this.options.max===this.options.min)return 0;if(this.options.ticks_positions.length>0){for(var b,c,d,e=0,f=0;f<this.options.ticks.length;f++)if(a<=this.options.ticks[f]){b=f>0?this.options.ticks[f-1]:0,d=f>0?this.options.ticks_positions[f-1]:0,c=this.options.ticks[f],e=this.options.ticks_positions[f];break}if(f>0){var g=(a-b)/(c-b);return d+g*(e-d)}}return 100*(a-this.options.min)/(this.options.max-this.options.min)}},logarithmic:{toValue:function(a){var b=0===this.options.min?0:Math.log(this.options.min),c=Math.log(this.options.max),d=Math.exp(b+(c-b)*a/100);return Math.round(d)===this.options.max?this.options.max:(d=this.options.min+Math.round((d-this.options.min)/this.options.step)*this.options.step,d<this.options.min?this.options.min:d>this.options.max?this.options.max:d)},toPercentage:function(a){if(this.options.max===this.options.min)return 0;var b=Math.log(this.options.max),c=0===this.options.min?0:Math.log(this.options.min),d=0===a?0:Math.log(a);return 100*(d-c)/(b-c)}}};if(d=function(a,b){return e.call(this,a,b),this},d.prototype={_init:function(){},constructor:d,defaultOptions:{id:"",min:0,max:10,step:1,precision:0,orientation:"horizontal",value:5,range:!1,selection:"before",tooltip:"show",tooltip_split:!1,handle:"round",reversed:!1,rtl:"auto",enabled:!0,formatter:function(a){return Array.isArray(a)?a[0]+" : "+a[1]:a},natural_arrow_keys:!1,ticks:[],ticks_positions:[],ticks_labels:[],ticks_snap_bounds:0,ticks_tooltip:!1,scale:"linear",focus:!1,tooltip_position:null,labelledby:null,rangeHighlights:[]},getElement:function(){return this.sliderElem},getValue:function(){return this.options.range?this._state.value:this._state.value[0]},setValue:function(a,b,c){a||(a=0);var d=this.getValue();this._state.value=this._validateInputValue(a);var e=this._applyPrecision.bind(this);this.options.range?(this._state.value[0]=e(this._state.value[0]),this._state.value[1]=e(this._state.value[1]),this._state.value[0]=Math.max(this.options.min,Math.min(this.options.max,this._state.value[0])),this._state.value[1]=Math.max(this.options.min,Math.min(this.options.max,this._state.value[1]))):(this._state.value=e(this._state.value),this._state.value=[Math.max(this.options.min,Math.min(this.options.max,this._state.value))],this._addClass(this.handle2,"hide"),"after"===this.options.selection?this._state.value[1]=this.options.max:this._state.value[1]=this.options.min),this.options.max>this.options.min?this._state.percentage=[this._toPercentage(this._state.value[0]),this._toPercentage(this._state.value[1]),100*this.options.step/(this.options.max-this.options.min)]:this._state.percentage=[0,0,100],this._layout();var f=this.options.range?this._state.value:this._state.value[0];return this._setDataVal(f),b===!0&&this._trigger("slide",f),d!==f&&c===!0&&this._trigger("change",{oldValue:d,newValue:f}),this},destroy:function(){this._removeSliderEventHandlers(),this.sliderElem.parentNode.removeChild(this.sliderElem),this.element.style.display="",this._cleanUpEventCallbacksMap(),this.element.removeAttribute("data"),a&&(this._unbindJQueryEventHandlers(),this.$element.removeData("slider"))},disable:function(){return this._state.enabled=!1,this.handle1.removeAttribute("tabindex"),this.handle2.removeAttribute("tabindex"),this._addClass(this.sliderElem,"slider-disabled"),this._trigger("slideDisabled"),this},enable:function(){return this._state.enabled=!0,this.handle1.setAttribute("tabindex",0),this.handle2.setAttribute("tabindex",0),this._removeClass(this.sliderElem,"slider-disabled"),this._trigger("slideEnabled"),this},toggle:function(){return this._state.enabled?this.disable():this.enable(),this},isEnabled:function(){return this._state.enabled},on:function(a,b){return this._bindNonQueryEventHandler(a,b),this},off:function(b,c){a?(this.$element.off(b,c),this.$sliderElem.off(b,c)):this._unbindNonQueryEventHandler(b,c)},getAttribute:function(a){return a?this.options[a]:this.options},setAttribute:function(a,b){return this.options[a]=b,this},refresh:function(){return this._removeSliderEventHandlers(),e.call(this,this.element,this.options),a&&a.data(this.element,"slider",this),this},relayout:function(){return this._resize(),this._layout(),this},_removeSliderEventHandlers:function(){if(this.handle1.removeEventListener("keydown",this.handle1Keydown,!1),this.handle2.removeEventListener("keydown",this.handle2Keydown,!1),this.options.ticks_tooltip){for(var a=this.ticksContainer.getElementsByClassName("slider-tick"),b=0;b<a.length;b++)a[b].removeEventListener("mouseenter",this.ticksCallbackMap[b].mouseEnter,!1),a[b].removeEventListener("mouseleave",this.ticksCallbackMap[b].mouseLeave,!1);this.handle1.removeEventListener("mouseenter",this.handleCallbackMap.handle1.mouseEnter,!1),this.handle2.removeEventListener("mouseenter",this.handleCallbackMap.handle2.mouseEnter,!1),this.handle1.removeEventListener("mouseleave",this.handleCallbackMap.handle1.mouseLeave,!1),this.handle2.removeEventListener("mouseleave",this.handleCallbackMap.handle2.mouseLeave,!1)}this.handleCallbackMap=null,this.ticksCallbackMap=null,this.showTooltip&&(this.handle1.removeEventListener("focus",this.showTooltip,!1),this.handle2.removeEventListener("focus",this.showTooltip,!1)),this.hideTooltip&&(this.handle1.removeEventListener("blur",this.hideTooltip,!1),this.handle2.removeEventListener("blur",this.hideTooltip,!1)),this.showTooltip&&this.sliderElem.removeEventListener("mouseenter",this.showTooltip,!1),this.hideTooltip&&this.sliderElem.removeEventListener("mouseleave",this.hideTooltip,!1),this.sliderElem.removeEventListener("touchstart",this.touchstart,!1),this.sliderElem.removeEventListener("touchmove",this.touchmove,!1),this.sliderElem.removeEventListener("mousedown",this.mousedown,!1),window.removeEventListener("resize",this.resize,!1)},_bindNonQueryEventHandler:function(a,b){void 0===this.eventToCallbackMap[a]&&(this.eventToCallbackMap[a]=[]),this.eventToCallbackMap[a].push(b)},_unbindNonQueryEventHandler:function(a,b){var c=this.eventToCallbackMap[a];if(void 0!==c)for(var d=0;d<c.length;d++)if(c[d]===b){c.splice(d,1);break}},_cleanUpEventCallbacksMap:function(){for(var a=Object.keys(this.eventToCallbackMap),b=0;b<a.length;b++){var c=a[b];delete this.eventToCallbackMap[c]}},_showTooltip:function(){this.options.tooltip_split===!1?(this._addClass(this.tooltip,"in"),this.tooltip_min.style.display="none",this.tooltip_max.style.display="none"):(this._addClass(this.tooltip_min,"in"),this._addClass(this.tooltip_max,"in"),this.tooltip.style.display="none"),this._state.over=!0},_hideTooltip:function(){this._state.inDrag===!1&&this.alwaysShowTooltip!==!0&&(this._removeClass(this.tooltip,"in"),this._removeClass(this.tooltip_min,"in"),this._removeClass(this.tooltip_max,"in")),this._state.over=!1},_setToolTipOnMouseOver:function(a){function b(a,b){return b?[100-a.percentage[0],this.options.range?100-a.percentage[1]:a.percentage[1]]:[a.percentage[0],a.percentage[1]]}var c=this.options.formatter(a?a.value[0]:this._state.value[0]),d=a?b(a,this.options.reversed):b(this._state,this.options.reversed);this._setText(this.tooltipInner,c),this.tooltip.style[this.stylePos]=d[0]+"%"},_addTickListener:function(){return{addMouseEnter:function(a,b,c){var d=function(){var b=a._state,d=c>=0?c:this.attributes["aria-valuenow"].value,e=parseInt(d,10);b.value[0]=e,b.percentage[0]=a.options.ticks_positions[e],a._setToolTipOnMouseOver(b),a._showTooltip()};return b.addEventListener("mouseenter",d,!1),d},addMouseLeave:function(a,b){var c=function(){a._hideTooltip()};return b.addEventListener("mouseleave",c,!1),c}}},_layout:function(){var a;if(a=this.options.reversed?[100-this._state.percentage[0],this.options.range?100-this._state.percentage[1]:this._state.percentage[1]]:[this._state.percentage[0],this._state.percentage[1]],this.handle1.style[this.stylePos]=a[0]+"%",this.handle1.setAttribute("aria-valuenow",this._state.value[0]),isNaN(this.options.formatter(this._state.value[0]))&&this.handle1.setAttribute("aria-valuetext",this.options.formatter(this._state.value[0])),this.handle2.style[this.stylePos]=a[1]+"%",this.handle2.setAttribute("aria-valuenow",this._state.value[1]),isNaN(this.options.formatter(this._state.value[1]))&&this.handle2.setAttribute("aria-valuetext",this.options.formatter(this._state.value[1])),this.rangeHighlightElements.length>0&&Array.isArray(this.options.rangeHighlights)&&this.options.rangeHighlights.length>0)for(var b=0;b<this.options.rangeHighlights.length;b++){var c=this._toPercentage(this.options.rangeHighlights[b].start),d=this._toPercentage(this.options.rangeHighlights[b].end);if(this.options.reversed){var e=100-d;d=100-c,c=e}var f=this._createHighlightRange(c,d);f?"vertical"===this.options.orientation?(this.rangeHighlightElements[b].style.top=f.start+"%",this.rangeHighlightElements[b].style.height=f.size+"%"):(this.options.rtl?this.rangeHighlightElements[b].style.right=f.start+"%":this.rangeHighlightElements[b].style.left=f.start+"%",this.rangeHighlightElements[b].style.width=f.size+"%"):this.rangeHighlightElements[b].style.display="none"}if(Array.isArray(this.options.ticks)&&this.options.ticks.length>0){var g,h="vertical"===this.options.orientation?"height":"width";g="vertical"===this.options.orientation?"marginTop":this.options.rtl?"marginRight":"marginLeft";var i=this._state.size/(this.options.ticks.length-1);if(this.tickLabelContainer){var j=0;if(0===this.options.ticks_positions.length)"vertical"!==this.options.orientation&&(this.tickLabelContainer.style[g]=-i/2+"px"),j=this.tickLabelContainer.offsetHeight;else for(k=0;k<this.tickLabelContainer.childNodes.length;k++)this.tickLabelContainer.childNodes[k].offsetHeight>j&&(j=this.tickLabelContainer.childNodes[k].offsetHeight);"horizontal"===this.options.orientation&&(this.sliderElem.style.marginBottom=j+"px")}for(var k=0;k<this.options.ticks.length;k++){var l=this.options.ticks_positions[k]||this._toPercentage(this.options.ticks[k]);this.options.reversed&&(l=100-l),this.ticks[k].style[this.stylePos]=l+"%",this._removeClass(this.ticks[k],"in-selection"),this.options.range?l>=a[0]&&l<=a[1]&&this._addClass(this.ticks[k],"in-selection"):"after"===this.options.selection&&l>=a[0]?this._addClass(this.ticks[k],"in-selection"):"before"===this.options.selection&&l<=a[0]&&this._addClass(this.ticks[k],"in-selection"),this.tickLabels[k]&&(this.tickLabels[k].style[h]=i+"px","vertical"!==this.options.orientation&&void 0!==this.options.ticks_positions[k]?(this.tickLabels[k].style.position="absolute",this.tickLabels[k].style[this.stylePos]=l+"%",this.tickLabels[k].style[g]=-i/2+"px"):"vertical"===this.options.orientation&&(this.options.rtl?this.tickLabels[k].style.marginRight=this.sliderElem.offsetWidth+"px":this.tickLabels[k].style.marginLeft=this.sliderElem.offsetWidth+"px",this.tickLabelContainer.style[g]=this.sliderElem.offsetWidth/2*-1+"px"))}}var m;if(this.options.range){m=this.options.formatter(this._state.value),this._setText(this.tooltipInner,m),this.tooltip.style[this.stylePos]=(a[1]+a[0])/2+"%";var n=this.options.formatter(this._state.value[0]);this._setText(this.tooltipInner_min,n);var o=this.options.formatter(this._state.value[1]);this._setText(this.tooltipInner_max,o),this.tooltip_min.style[this.stylePos]=a[0]+"%",this.tooltip_max.style[this.stylePos]=a[1]+"%"}else m=this.options.formatter(this._state.value[0]),this._setText(this.tooltipInner,m),this.tooltip.style[this.stylePos]=a[0]+"%";if("vertical"===this.options.orientation)this.trackLow.style.top="0",this.trackLow.style.height=Math.min(a[0],a[1])+"%",this.trackSelection.style.top=Math.min(a[0],a[1])+"%",this.trackSelection.style.height=Math.abs(a[0]-a[1])+"%",this.trackHigh.style.bottom="0",this.trackHigh.style.height=100-Math.min(a[0],a[1])-Math.abs(a[0]-a[1])+"%";else{"right"===this.stylePos?this.trackLow.style.right="0":this.trackLow.style.left="0",this.trackLow.style.width=Math.min(a[0],a[1])+"%","right"===this.stylePos?this.trackSelection.style.right=Math.min(a[0],a[1])+"%":this.trackSelection.style.left=Math.min(a[0],a[1])+"%",this.trackSelection.style.width=Math.abs(a[0]-a[1])+"%","right"===this.stylePos?this.trackHigh.style.left="0":this.trackHigh.style.right="0",this.trackHigh.style.width=100-Math.min(a[0],a[1])-Math.abs(a[0]-a[1])+"%";var p=this.tooltip_min.getBoundingClientRect(),q=this.tooltip_max.getBoundingClientRect();"bottom"===this.options.tooltip_position?p.right>q.left?(this._removeClass(this.tooltip_max,"bottom"),this._addClass(this.tooltip_max,"top"),this.tooltip_max.style.top="",this.tooltip_max.style.bottom="22px"):(this._removeClass(this.tooltip_max,"top"),this._addClass(this.tooltip_max,"bottom"),this.tooltip_max.style.top=this.tooltip_min.style.top,this.tooltip_max.style.bottom=""):p.right>q.left?(this._removeClass(this.tooltip_max,"top"),this._addClass(this.tooltip_max,"bottom"),this.tooltip_max.style.top="18px"):(this._removeClass(this.tooltip_max,"bottom"),this._addClass(this.tooltip_max,"top"),this.tooltip_max.style.top=this.tooltip_min.style.top)}},_createHighlightRange:function(a,b){return this._isHighlightRange(a,b)?a>b?{start:b,size:a-b}:{start:a,size:b-a}:null},_isHighlightRange:function(a,b){return a>=0&&100>=a&&b>=0&&100>=b?!0:!1},_resize:function(a){this._state.offset=this._offset(this.sliderElem),this._state.size=this.sliderElem[this.sizePos],this._layout()},_removeProperty:function(a,b){a.style.removeProperty?a.style.removeProperty(b):a.style.removeAttribute(b)},_mousedown:function(a){if(!this._state.enabled)return!1;this._state.offset=this._offset(this.sliderElem),this._state.size=this.sliderElem[this.sizePos];var b=this._getPercentage(a);if(this.options.range){var c=Math.abs(this._state.percentage[0]-b),d=Math.abs(this._state.percentage[1]-b);this._state.dragged=d>c?0:1,this._adjustPercentageForRangeSliders(b)}else this._state.dragged=0;this._state.percentage[this._state.dragged]=b,this._layout(),this.touchCapable&&(document.removeEventListener("touchmove",this.mousemove,!1),document.removeEventListener("touchend",this.mouseup,!1)),this.mousemove&&document.removeEventListener("mousemove",this.mousemove,!1),this.mouseup&&document.removeEventListener("mouseup",this.mouseup,!1),this.mousemove=this._mousemove.bind(this),this.mouseup=this._mouseup.bind(this),this.touchCapable&&(document.addEventListener("touchmove",this.mousemove,!1),document.addEventListener("touchend",this.mouseup,!1)),document.addEventListener("mousemove",this.mousemove,!1),document.addEventListener("mouseup",this.mouseup,!1),this._state.inDrag=!0;var e=this._calculateValue();return this._trigger("slideStart",e),this._setDataVal(e),this.setValue(e,!1,!0),a.returnValue=!1,this.options.focus&&this._triggerFocusOnHandle(this._state.dragged),!0},_touchstart:function(a){if(void 0===a.changedTouches)return void this._mousedown(a);var b=a.changedTouches[0];this.touchX=b.pageX,this.touchY=b.pageY},_triggerFocusOnHandle:function(a){0===a&&this.handle1.focus(),1===a&&this.handle2.focus()},_keydown:function(a,b){if(!this._state.enabled)return!1;var c;switch(b.keyCode){case 37:case 40:c=-1;break;case 39:case 38:c=1}if(c){if(this.options.natural_arrow_keys){var d="vertical"===this.options.orientation&&!this.options.reversed,e="horizontal"===this.options.orientation&&this.options.reversed;(d||e)&&(c=-c)}var f=this._state.value[a]+c*this.options.step,g=f/this.options.max*100;if(this._state.keyCtrl=a,this.options.range){this._adjustPercentageForRangeSliders(g);var h=this._state.keyCtrl?this._state.value[0]:f,i=this._state.keyCtrl?f:this._state.value[1];f=[h,i]}return this._trigger("slideStart",f),this._setDataVal(f),this.setValue(f,!0,!0),this._setDataVal(f),this._trigger("slideStop",f),this._layout(),this._pauseEvent(b),delete this._state.keyCtrl,!1}},_pauseEvent:function(a){a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault(),a.cancelBubble=!0,a.returnValue=!1},_mousemove:function(a){if(!this._state.enabled)return!1;var b=this._getPercentage(a);this._adjustPercentageForRangeSliders(b),this._state.percentage[this._state.dragged]=b,this._layout();var c=this._calculateValue(!0);return this.setValue(c,!0,!0),!1},_touchmove:function(a){if(void 0!==a.changedTouches){var b=a.changedTouches[0],c=b.pageX-this.touchX,d=b.pageY-this.touchY;this._state.inDrag||("vertical"===this.options.orientation&&5>=c&&c>=-5&&(d>=15||-15>=d)?this._mousedown(a):5>=d&&d>=-5&&(c>=15||-15>=c)&&this._mousedown(a))}},_adjustPercentageForRangeSliders:function(a){if(this.options.range){var b=this._getNumDigitsAfterDecimalPlace(a);b=b?b-1:0;var c=this._applyToFixedAndParseFloat(a,b);0===this._state.dragged&&this._applyToFixedAndParseFloat(this._state.percentage[1],b)<c?(this._state.percentage[0]=this._state.percentage[1],this._state.dragged=1):1===this._state.dragged&&this._applyToFixedAndParseFloat(this._state.percentage[0],b)>c?(this._state.percentage[1]=this._state.percentage[0],this._state.dragged=0):0===this._state.keyCtrl&&this._state.value[1]/this.options.max*100<a?(this._state.percentage[0]=this._state.percentage[1],this._state.keyCtrl=1,this.handle2.focus()):1===this._state.keyCtrl&&this._state.value[0]/this.options.max*100>a&&(this._state.percentage[1]=this._state.percentage[0],this._state.keyCtrl=0,this.handle1.focus())}},_mouseup:function(){if(!this._state.enabled)return!1;this.touchCapable&&(document.removeEventListener("touchmove",this.mousemove,!1),document.removeEventListener("touchend",this.mouseup,!1)),document.removeEventListener("mousemove",this.mousemove,!1),document.removeEventListener("mouseup",this.mouseup,!1),this._state.inDrag=!1,this._state.over===!1&&this._hideTooltip();var a=this._calculateValue(!0);return this._layout(),this._setDataVal(a),this._trigger("slideStop",a),!1},_calculateValue:function(a){var b;if(this.options.range?(b=[this.options.min,this.options.max],0!==this._state.percentage[0]&&(b[0]=this._toValue(this._state.percentage[0]),b[0]=this._applyPrecision(b[0])),100!==this._state.percentage[1]&&(b[1]=this._toValue(this._state.percentage[1]),b[1]=this._applyPrecision(b[1]))):(b=this._toValue(this._state.percentage[0]),b=parseFloat(b),b=this._applyPrecision(b)),a){for(var c=[b,1/0],d=0;d<this.options.ticks.length;d++){var e=Math.abs(this.options.ticks[d]-b);e<=c[1]&&(c=[this.options.ticks[d],e])}if(c[1]<=this.options.ticks_snap_bounds)return c[0]}return b},_applyPrecision:function(a){var b=this.options.precision||this._getNumDigitsAfterDecimalPlace(this.options.step);return this._applyToFixedAndParseFloat(a,b)},_getNumDigitsAfterDecimalPlace:function(a){var b=(""+a).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return b?Math.max(0,(b[1]?b[1].length:0)-(b[2]?+b[2]:0)):0},_applyToFixedAndParseFloat:function(a,b){var c=a.toFixed(b);return parseFloat(c)},_getPercentage:function(a){!this.touchCapable||"touchstart"!==a.type&&"touchmove"!==a.type||(a=a.touches[0]);var b=a[this.mousePos],c=this._state.offset[this.stylePos],d=b-c;"right"===this.stylePos&&(d=-d);var e=d/this._state.size*100;return e=Math.round(e/this._state.percentage[2])*this._state.percentage[2],this.options.reversed&&(e=100-e),Math.max(0,Math.min(100,e))},_validateInputValue:function(a){if(isNaN(+a)){if(Array.isArray(a))return this._validateArray(a),a;throw new Error(f.formatInvalidInputErrorMsg(a))}return+a},_validateArray:function(a){for(var b=0;b<a.length;b++){
-var c=a[b];if("number"!=typeof c)throw new Error(f.formatInvalidInputErrorMsg(c))}},_setDataVal:function(a){this.element.setAttribute("data-value",a),this.element.setAttribute("value",a),this.element.value=a},_trigger:function(b,c){c=c||0===c?c:void 0;var d=this.eventToCallbackMap[b];if(d&&d.length)for(var e=0;e<d.length;e++){var f=d[e];f(c)}a&&this._triggerJQueryEvent(b,c)},_triggerJQueryEvent:function(a,b){var c={type:a,value:b};this.$element.trigger(c),this.$sliderElem.trigger(c)},_unbindJQueryEventHandlers:function(){this.$element.off(),this.$sliderElem.off()},_setText:function(a,b){"undefined"!=typeof a.textContent?a.textContent=b:"undefined"!=typeof a.innerText&&(a.innerText=b)},_removeClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)");d=d.replace(g," ")}a.className=d.trim()},_addClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)"),h=g.test(d);h||(d+=" "+f)}a.className=d.trim()},_offsetLeft:function(a){return a.getBoundingClientRect().left},_offsetRight:function(a){return a.getBoundingClientRect().right},_offsetTop:function(a){for(var b=a.offsetTop;(a=a.offsetParent)&&!isNaN(a.offsetTop);)b+=a.offsetTop,"BODY"!==a.tagName&&(b-=a.scrollTop);return b},_offset:function(a){return{left:this._offsetLeft(a),right:this._offsetRight(a),top:this._offsetTop(a)}},_css:function(b,c,d){if(a)a.style(b,c,d);else{var e=c.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,b){return b.toUpperCase()});b.style[e]=d}},_toValue:function(a){return this.options.scale.toValue.apply(this,[a])},_toPercentage:function(a){return this.options.scale.toPercentage.apply(this,[a])},_setTooltipPosition:function(){var a=[this.tooltip,this.tooltip_min,this.tooltip_max];if("vertical"===this.options.orientation){var b;b=this.options.tooltip_position?this.options.tooltip_position:this.options.rtl?"left":"right";var c="left"===b?"right":"left";a.forEach(function(a){this._addClass(a,b),a.style[c]="100%"}.bind(this))}else"bottom"===this.options.tooltip_position?a.forEach(function(a){this._addClass(a,"bottom"),a.style.top="22px"}.bind(this)):a.forEach(function(a){this._addClass(a,"top"),a.style.top=-this.tooltip.outerHeight-14+"px"}.bind(this))}},a&&a.fn){var h=void 0;a.fn.slider?(windowIsDefined&&window.console.warn("bootstrap-slider.js - WARNING: $.fn.slider namespace is already bound. Use the $.fn.bootstrapSlider namespace instead."),h=c):(a.bridget(b,d),h=b),a.bridget(c,d),a(function(){a("input[data-provide=slider]")[h]()})}}(a),d});
diff --git a/examples/esp8266/EscControl/EscControl/data/img/icon.png b/examples/esp8266/EscControl/EscControl/data/img/icon.png
deleted file mode 100644
index f1f4d8e1..00000000
Binary files a/examples/esp8266/EscControl/EscControl/data/img/icon.png and /dev/null differ
diff --git a/examples/esp8266/EscControl/EscControl/data/img/logo.png b/examples/esp8266/EscControl/EscControl/data/img/logo.png
deleted file mode 100644
index f1f4d8e1..00000000
Binary files a/examples/esp8266/EscControl/EscControl/data/img/logo.png and /dev/null differ
diff --git a/examples/esp8266/WebMenu/.gitignore b/examples/esp8266/WebMenu/.gitignore
deleted file mode 100644
index e05273b2..00000000
--- a/examples/esp8266/WebMenu/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.clang_complete
-.gcc-flags.json
-.piolibdeps
\ No newline at end of file
diff --git a/examples/esp8266/WebMenu/.travis.yml b/examples/esp8266/WebMenu/.travis.yml
deleted file mode 100644
index 72c6e43f..00000000
--- a/examples/esp8266/WebMenu/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/en/stable/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/en/stable/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/en/stable/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/esp8266/WebMenu/WebMenu/WebMenu.ino b/examples/esp8266/WebMenu/WebMenu/WebMenu.ino
deleted file mode 100644
index 554d103d..00000000
--- a/examples/esp8266/WebMenu/WebMenu/WebMenu.ino
+++ /dev/null
@@ -1,468 +0,0 @@
-/********************
-Arduino generic menu system
-XmlServer menu example
-based on WebServer:
-  https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer
-  https://github.com/Links2004/arduinoWebSockets
-
-Dec. 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu on web browser served by esp8266 device
-output: ESP8266WebServer -> Web browser
-input: ESP8266WebSocket <- Web browser
-format: xml, json
-
-IMPORTANT!:
-this requires the data folder to be stored on esp8266 spiff
-Extra libraries should be present
-
-arduinoWebSockets - https://github.com/Links2004/arduinoWebSockets
-ESP8266WiFi - https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WiFi
-ESP8266WebServer - https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer
-
-for development purposes some files are left external,
-therefor requiring an external webserver to provide them (just for dev purposes)
-i'm using nodejs http-server (https://www.npmjs.com/package/http-server)
-to static serve content from the data folder. This allows me to quick change
-the files without having to upload them to SPIFFS
-also gateway ssid and password are stored on this code (bellow),
-so don't forget to change it.
-
-*/
-
-#include <menu.h>
-#include <menuIO/esp8266Out.h>
-#include <menuIO/xmlFmt.h>//to write a menu has html page
-#include <menuIO/serialIn.h>
-#include <menuIO/xmlFmt.h>//to write a menu has xml page
-#include <menuIO/jsonFmt.h>//to write a menu has xml page
-#ifndef ARDUINO_STREAMING
-  #include <streamFlow.h>//https://github.com/neu-rah/streamFlow
-#else
-  #include <Streaming.h>//https://github.com/scottdky/Streaming
-#endif
-//#include <menuIO/jsFmt.h>//to send javascript thru web socket (live update)
-#include <FS.h>
-#include <Hash.h>
-extern "C" {
-  #include "user_interface.h"
-}
-
-using namespace Menu;
-
-#ifdef WEB_DEBUG
-  // on debug mode I put aux files on external server to allow changes without SPIFF update
-  // on this mode the browser MUST be instructed to accept cross domain files
-  String xslt("http://neurux:8080/");
-#else
-  String xslt("");
-#endif
-
-menuOut& operator<<(menuOut& o,unsigned long int i) {
-  o.print(i);
-  return o;
-}
-menuOut& operator<<(menuOut& o,endlObj) {
-  o.println();
-  return o;
-}
-
-//this version numbers MUST be the same as data/1.2
-#define CUR_VERSION "1.5"
-#define APName "WebMenu"
-
-int ledCtrl=LOW;
-//on my esp12e led pin is 2
-#define LEDPIN 2
-//this is ok on other boards
-// #define LEDPIN LED_BUILTIN
-void updLed() {
-  _trace(Serial<<"update led state!"<<endl);
-  digitalWrite(LEDPIN,!ledCtrl);
-}
-
-#define ANALOG_PIN 4
-
-// constexpr size_t wifiSSIDLen=64;
-// constexpr size_t wifiPwdLen=32;
-
-#ifndef MENU_SSID
-  #error "need to define WiFi SSID here"
-  #define MENU_SSID "r-site.net"
-#endif
-#ifndef MENU_PASS
-  #error "need to define WiFi password here"
-  #define MENU_PASS ""
-#endif
-
-// char wifiSSID[wifiSSIDLen+1];//="                                ";
-// char wifiPwd [wifiPwdLen+1];//="                                ";
-
-const char* ssid = MENU_SSID;
-const char* password = MENU_PASS;
-const char* serverName="192.168.1.79";
-
-#define HTTP_PORT 80
-#define WS_PORT 81
-#define USE_SERIAL Serial
-ESP8266WebServer server(80);
-WebSocketsServer webSocket(81);
-
-#define MAX_DEPTH 2
-idx_t web_tops[MAX_DEPTH];
-PANELS(webPanels,{0,0,80,100});
-xmlFmt<esp8266_WebServerStreamOut> serverOut(server,web_tops,webPanels);
-jsonFmt<esp8266_WebServerStreamOut> jsonOut(server,web_tops,webPanels);
-jsonFmt<esp8266BufferedOut> wsOut(web_tops,webPanels);
-
-//menu action functions
-result action1(eventMask event, navNode& nav, prompt &item) {
-  Serial.println("action A called!");
-  serverOut<<"This is action <b>A</b> web report "<<(millis()%1000)<<"<br/>";
-  return proceed;
-}
-result action2(eventMask event, navNode& nav, prompt &item) {
-  Serial.println("action B called!");
-  serverOut<<"This is action <b>B</b> web report "<<(millis()%1000)<<"<br/>";
-  return proceed;
-}
-
-void debugLedUpd() {
-  _trace(Serial<<"debug led update! "<<ledCtrl<<endl);
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",updLed,(Menu::eventMask)(updateEvent|enterEvent),noStyle
-  ,VALUE("Off",LOW,doNothing,noEvent)
-  ,VALUE("On",HIGH,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-int duty=50;//%
-int timeOn=50;//ms
-void updAnalog() {
-  // analogWrite(ANALOG_PIN,map(timeOn,0,100,0,255/*PWMRANGE*/));
-  analogWrite(ANALOG_PIN,map(duty,0,100,0,255/*PWMRANGE*/));
-}
-
-char* constMEM alphaNum MEMMODE=" 0123456789.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,\\|!\"#$%&/()=?~*^+-{}[]€";
-char* constMEM alphaNumMask[] MEMMODE={alphaNum};
-char name[]="                                                  ";
-
-uint16_t year=2017;
-uint16_t month=10;
-uint16_t day=7;
-
-//define a pad style menu (single line menu)
-//here with a set of fields to enter a date in YYYY/MM/DD format
-//altMENU(menu,birthDate,"Birth",doNothing,noEvent,noStyle,(systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
-PADMENU(birthDate,"Birth",doNothing,noEvent,noStyle
-  ,FIELD(year,"","/",1900,3000,20,1,doNothing,noEvent,noStyle)
-  ,FIELD(month,"","/",1,12,1,0,doNothing,noEvent,wrapStyle)
-  ,FIELD(day,"","",1,31,1,0,doNothing,noEvent,wrapStyle)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  // altPrompt(constMEM promptShadow& p):prompt(p) {}
-  using prompt::prompt;
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);
-  }
-};
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,OP("Sub1",doNothing,noEvent)
-  ,OP("Sub2",doNothing,noEvent)
-  ,OP("Sub3",doNothing,noEvent)
-  ,altOP(altPrompt,"",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-//the menu
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,SUBMENU(setLed)
-  ,OP("Action A",action1,enterEvent)
-  ,OP("Action B",action2,enterEvent)
-  ,FIELD(duty,"Duty","%",0,100,10,1, updAnalog, anyEvent, noStyle)
-  // ,FIELD(timeOn,"On","ms",0,100,10,1, updAnalog, anyEvent, noStyle)
-  ,EDIT("Name",name,alphaNumMask,doNothing,noEvent,noStyle)
-  ,SUBMENU(birthDate)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,SUBMENU(subMenu)
-  ,EXIT("Exit!")
-);
-
-result idle(menuOut& o,idleEvent e) {
-  //if (e==idling)
-  Serial.println("suspended");
-  o<<"suspended..."<<endl<<"press [select]"<<endl<<"to continue"<<endl<<(millis()%1000);
-  return quit;
-}
-
-template<typename T>//some utill to help us calculate array sizes (known at compile time)
-constexpr inline size_t len(T& o) {return sizeof(o)/sizeof(decltype(o[0]));}
-
-//serial menu navigation
-MENU_OUTLIST(out,&serverOut);
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-//xml+http navigation control
-noInput none;//web uses its own API
-menuOut* web_outputs[]={&serverOut};
-outputsList web_out(web_outputs,len(web_outputs));
-navNode web_cursors[MAX_DEPTH];
-navRoot webNav(mainMenu, web_cursors, MAX_DEPTH, none, web_out);
-
-//json+http navigation control
-menuOut* json_outputs[]={&jsonOut};
-outputsList json_out(json_outputs,len(json_outputs));
-navNode json_cursors[MAX_DEPTH];
-navRoot jsonNav(mainMenu, json_cursors, MAX_DEPTH, none, json_out);
-
-//websockets navigation control
-menuOut* ws_outputs[]={&wsOut};
-outputsList ws_out(ws_outputs,len(ws_outputs));
-navNode ws_cursors[MAX_DEPTH];
-navRoot wsNav(mainMenu, ws_cursors, MAX_DEPTH, none, ws_out);
-
-//config myOptions('*','-',defaultNavCodes,false);
-
-void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
-  switch(type) {
-    case WStype_DISCONNECTED:
-      //USE_SERIAL.printf("[%u] Disconnected!\n", num);
-      break;
-    case WStype_CONNECTED: {
-        IPAddress ip = webSocket.remoteIP(num);
-        //USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
-        webSocket.sendTXT(num, "console.log('ArduinoMenu Connected')");
-      }
-      break;
-    case WStype_TEXT: {
-        //USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
-        // nav.async((const char*)payload);//this is slow!!!!!!!!
-        __trace(Serial.printf("[%u] get Text: %s\n", num, payload));
-        char*s=(char*)payload;
-        _trace(Serial<<"serve websocket menu"<<endl);
-        wsOut.response.remove(0);
-        wsOut<<"{\"output\":\"";
-        wsNav.async((const char*)payload);
-        wsOut<<"\",\n\"menu\":";
-        wsNav.doOutput();
-        wsOut<<"\n}";
-        webSocket.sendTXT(num,wsOut.response);
-        // wsOut.response.remove(0);
-        // jsonEnd();
-      } break;
-    case WStype_BIN: {
-        USE_SERIAL<<"[WSc] get binary length:"<<length<<"[";
-        for(int c=0;c<length;c++) {
-          USE_SERIAL.print(*(char*)(payload+c),HEX);
-          USE_SERIAL.write(',');
-        }
-        USE_SERIAL<<"]"<<endl;
-        uint16_t id=*(uint16_t*) payload++;
-        idx_t len=*((idx_t*)++payload);
-        idx_t* pathBin=(idx_t*)++payload;
-        const char* inp=(const char*)(payload+len);
-        //Serial<<"id:"<<id<<endl;
-        if (id==nav.active().hash()) {
-          //Serial<<"id ok."<<endl;Serial.flush();
-          //Serial<<"input:"<<inp<<endl;
-          //StringStream inStr(inp);
-          //while(inStr.available())
-          nav.doInput(inp);
-          webSocket.sendTXT(num, "binBusy=false;");//send javascript to unlock the state
-        } //else Serial<<"id not ok!"<<endl;
-        //Serial<<endl;
-      }
-      break;
-    default:break;
-  }
-}
-
-void pageStart() {
-  _trace(Serial<<"pasgeStart!"<<endl);
-  serverOut<<"HTTP/1.1 200 OK\r\n"
-    <<"Content-Type: text/xml\r\n"
-    <<"Connection: close\r\n"
-    <<"Expires: 0\r\n"
-    <<"\r\n";
-  serverOut<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n"
-    "<?xml-stylesheet type=\"text/xsl\" href=\"";
-  serverOut<<xslt;
-  serverOut<<CUR_VERSION"/device.xslt";
-  serverOut<<"\"?>\r\n<menuLib"
-    #ifdef WEB_DEBUG
-      <<" debug=\"yes\""
-    #endif
-    <<" host=\"";
-    serverOut.print(APName);
-    serverOut<<"\">\r\n<sourceURL ver=\"" CUR_VERSION "/\">";
-  if (server.hasHeader("host"))
-    serverOut.print(server.header("host"));
-  else
-    serverOut.print(APName);
-  serverOut<<"</sourceURL>";
-}
-
-void pageEnd() {
-  serverOut<<"</menuLib>";
-  server.client().stop();
-}
-
-void jsonStart() {
-  _trace(Serial<<"jsonStart!"<<endl);
-  serverOut<<"HTTP/1.1 200 OK\r\n"
-    <<"Content-Type: application/json; charset=utf-8\r\n"
-    <<"Connection: close\r\n"
-    <<"Expires: 0\r\n"
-    <<"\r\n";
-}
-
-void jsonEnd() {
-  server.client().stop();
-}
-
-bool handleMenu(navRoot& nav){
-  _trace(
-    uint32_t free = system_get_free_heap_size();
-    Serial.print(F("free memory:"));
-    Serial.print(free);
-    Serial.print(F(" handleMenu "));
-    Serial.println(server.arg("at").c_str());
-  );
-  String at=server.arg("at");
-  bool r;
-  r=nav.async(server.hasArg("at")?at.c_str():"/");
-  return r;
-}
-
-//redirect to version folder,
-//this allows agressive caching with no need to cache reset on version change
-auto mainPage= []() {
-  _trace(Serial<<"serving main page from root!"<<endl);
-  server.sendHeader("Location", CUR_VERSION "/index.html", true);
-  server.send ( 302, "text/plain", "");
-  if (server.hasArg("at"))
-    nav.async(server.arg("at").c_str());
-};
-
-void setup(){
-  //check your pins before activating this
-  pinMode(LEDPIN,OUTPUT);
-  updLed();
-  // analogWriteRange(1023);
-  pinMode(ANALOG_PIN,OUTPUT);
-  updAnalog();
-  //options=&myOptions;//menu options
-  Serial.begin(115200);
-  while(!Serial)
-  //USE_SERIAL.setDebugOutput(true);
-  Serial.println();
-  Serial.println();
-  Serial.println();
-
-  // #ifndef MENU_DEBUG
-    //do not allow web heads to exit, they wont be able to return (for now)
-    //we should resume this heads on async requests!
-    webNav.canExit=false;
-    jsonNav.canExit=false;
-    wsNav.canExit=false;
-  // #endif
-
-  for(uint8_t t = 4; t > 0; t--) {
-      Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
-      Serial.flush();
-      delay(1000);
-  }
-
-  // Serial.setDebugOutput(1);
-  // Serial.setDebugOutput(0);
-  // while(!Serial);
-  // delay(10);
-  // wifi_station_set_hostname((char*)serverName);
-  Serial.println("");
-  Serial.println("Arduino menu webserver example");
-
-  SPIFFS.begin();
-
-  Serial.print("Connecting to ");
-  Serial.println(ssid);
-
-  WiFi.begin(ssid, password);
-  // Wait for connection
-  while (WiFi.status() != WL_CONNECTED) {
-    delay(500);
-    Serial.print(".");
-  }
-  webSocket.begin();
-  Serial.println("");
-  webSocket.onEvent(webSocketEvent);
-  Serial.println("Connected.");
-  Serial.print("IP address: ");
-  Serial.println(WiFi.localIP());
-
-  webSocket.begin();
-
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-
-  server.on("/",HTTP_GET,mainPage);
-
-  //menu xml server over http
-  server.on("/menu", HTTP_GET, []() {
-    pageStart();
-    serverOut<<"<output state=\""<<((int)&webNav.idleTask)<<"\"><![CDATA[";
-    _trace(Serial<<"output count"<<webNav.out.cnt<<endl);
-    handleMenu(webNav);//do navigation (read input) and produce output messages or reports
-    serverOut<<"]]></output>";
-    webNav.doOutput();
-    pageEnd();
-  });
-
-  //menu json server over http
-  server.on("/json", HTTP_GET, []() {
-    _trace(Serial<<"json request!"<<endl);
-    jsonStart();
-    serverOut<<"{\"output\":\"";
-    handleMenu(jsonNav);
-    serverOut<<"\",\n\"menu\":";
-    jsonNav.doOutput();
-    serverOut<<"\n}";
-    jsonEnd();
-  });
-
-  server.begin();
-  Serial.println("HTTP server started");
-  Serial.println("Serving ArduinoMenu example.");
-  #ifdef MENU_DEBUG
-    server.serveStatic("/", SPIFFS, "/","max-age=30");
-  #else
-    server.serveStatic("/", SPIFFS, "/","max-age=31536000");
-  #endif
-}
-
-void loop(void){
-  wsOut.response.remove(0);//clear websocket json buffer
-  webSocket.loop();
-  server.handleClient();
-  delay(1);
-}
diff --git a/examples/esp8266/WebMenu/WebMenu/data/1.5/bootstrap.xslt b/examples/esp8266/WebMenu/WebMenu/data/1.5/bootstrap.xslt
deleted file mode 100644
index f02ff178..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/1.5/bootstrap.xslt
+++ /dev/null
@@ -1,307 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-	xmlns:dyn="http://exslt.org/dynamic">
-
-  <!-- result of the last request -->
-  <xsl:template match="output">
-    <div id="outDlg" class="modal" tabindex="-1" role="dialog">
-      <div class="modal-dialog" role="document">
-        <div class="modal-content">
-          <div class="modal-header">
-            <h3 class="modal-title">Arduino&lt;Web&gt;Menu </h3>
-            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-              <span aria-hidden="true"><xsl:text disable-output-escaping="yes">X</xsl:text></span>
-            </button>
-          </div>
-          <div class="modal-body">
-            <p class="out"><xsl:value-of select="." disable-output-escaping="yes"/></p>
-          </div>
-          <div class="modal-footer">
-            <button type="button" class="btn btn-primary" data-dismiss="modal">Ok</button>
-          </div>
-        </div>
-      </div>
-    </div>
-  </xsl:template>
-
-  <xsl:template match="*">
-    <xsl:apply-templates/>
-  </xsl:template>
-
-  <xsl:template match="sourceURL">
-    <h2 class="sourceURL"><xsl:value-of select="../@host"/></h2>
-  </xsl:template>
-
-  <xsl:template match="menuLib/panel">
-    <div class="aml_panel"><xsl:apply-templates/></div>
-  </xsl:template>
-
-  <xsl:template match="menuLib/panel/tit">
-    <h3><xsl:apply-templates/></h3>
-  </xsl:template>
-
-  <xsl:template match="menu">
-    <ul><xsl:apply-templates/></ul>
-  </xsl:template>
-
-  <xsl:template match="op">
-    <li class="row aml_op btn btn-lg btn-success">
-      <xsl:apply-templates/>
-    </li>
-  </xsl:template>
-
-  <xsl:template match="p[@t='menu']">
-    <xsl:call-template name="linkBtn"/>
-  </xsl:template>
-
-  <xsl:template match="p[@t='mn']" mode="pad">
-    <xsl:call-template name="linkBtn"/>
-  </xsl:template>
-
-  <xsl:template name="linkBtn">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor-or-self::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <xsl:choose>
-      <xsl:when test="@dis='y'">
-        <xsl:apply-templates/>
-      </xsl:when>
-      <xsl:otherwise>
-        <a href="/menu?at={$path}">
-          <xsl:apply-templates/>
-        </a>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-
-  <xsl:template match="op[ob/p/@t='prompt']|op[ob/p/@t='mn']">
-    <xsl:choose>
-      <xsl:when test="@dis='y'">
-        <li class="row aml_op btn btn-lg btn-disabled">
-          <xsl:call-template name="linkBtn"/>
-        </li>
-      </xsl:when>
-      <xsl:otherwise>
-        <li class="row aml_op btn btn-lg btn-success linkBtn">
-          <xsl:call-template name="linkBtn"/>
-        </li>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-
-  <xsl:template match="op[ob/p/@t='prompt']|op[ob/p/@t='mn']" mode="pad">
-    <div class="padOp"><xsl:call-template name="linkBtn"/></div>
-  </xsl:template>
-
-  <xsl:template match="op[@pad='y']">
-    <li class="row aml_op btn btn-lg btn-success">
-      <xsl:apply-templates mode="pad"/>
-    </li>
-  </xsl:template>
-
-  <!-- toggle field -->
-  <xsl:template match="tog">
-    <xsl:apply-templates select="node/value" mode="btns"/>
-  </xsl:template>
-
-  <!-- toggle field -->
-  <xsl:template match="tog" mode="pad">
-    <xsl:apply-templates select="node/value" mode="btns"/>
-  </xsl:template>
-
-  <xsl:template match="fld" mode="pad">
-    <xsl:apply-templates select="."/>
-  </xsl:template>
-
-  <!-- toggle option -->
-  <xsl:template match="node/value" mode="btns">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <a class="aml_btn btn btn-md btn-success" data-grp="{$path}" data-src="{$path}/{position()-1}" href="/menu?at={$path}/{position()-1}">
-      <xsl:apply-templates/>
-    </a>
-  </xsl:template>
-
-  <!-- toggle current option -->
-  <xsl:template match="node/value[@selected]" mode="btns">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <a class="aml_btn btn btn-md btn-primary" data-grp="{$path}" data-src="{$path}/{position()-1}" href="/menu?at={$path}/{position()-1}">
-      <xsl:apply-templates/>
-    </a>
-  </xsl:template>
-
-  <!-- ignorered stuff -->
-  <xsl:template name="ignore" match="cur|fv"/>
-  <xsl:template name="ignorePad" match="cur|fv" mode="pad"/>
-
-  <!-- <xsl:template match="fld[../p[@t='f']]">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <xsl:element name="input">
-      <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="type">text</xsl:attribute>
-      <xsl:attribute name="class">slider ledField</xsl:attribute>
-      <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-      <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-      <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-      <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="data-src"><xsl:value-of select="$path"/></xsl:attribute>
-      <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-    </xsl:element>
-  </xsl:template> -->
-
-  <xsl:template match="fld[../u='%']">
-    <xsl:variable name="path">
-      <xsl:value-of select="ancestor::*/@r"/>
-      <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-    </xsl:variable>
-    <xsl:element name="input">
-      <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-      <xsl:attribute name="type">text</xsl:attribute>
-      <xsl:attribute name="class">slider ledField</xsl:attribute>
-      <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-      <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-      <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-      <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-      <xsl:attribute name="data-src"><xsl:value-of select="$path"/></xsl:attribute>
-      <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-    </xsl:element>
-  </xsl:template>
-
-  <xsl:template match="fld">
-    <xsl:call-template name="fld">
-      <xsl:with-param name="at">
-        <xsl:value-of select="ancestor::*/@r"/>
-        <xsl:for-each select="ancestor::*/@i">/<xsl:value-of select="."/></xsl:for-each>
-      </xsl:with-param>
-      <xsl:with-param name="type"><xsl:value-of select="../p/@t"/></xsl:with-param>
-    </xsl:call-template>
-  </xsl:template>
-
-  <xsl:template name="fld">
-    <xsl:param name="at"/>
-    <xsl:param name="type"/>
-    <xsl:variable name="ln">
-      <xsl:choose>
-        <xsl:when test="@t>0">
-          <xsl:value-of select="(@h - @l) div @t"/>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:value-of select="(@h - @l) div @s"/>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:variable>
-    <xsl:variable name="szBase">
-      <xsl:choose>
-        <xsl:when test="@h&lt;10 and @l&gt;-10">1</xsl:when>
-        <xsl:when test="@h&lt;100 and @l&gt;-100">2</xsl:when>
-        <xsl:when test="@h&lt;1000 and @l&gt;-1000">3</xsl:when>
-        <xsl:when test="@h&lt;10000 and @l&gt;-10000">4</xsl:when>
-        <xsl:otherwise>8</xsl:otherwise>
-      </xsl:choose>
-    </xsl:variable>
-    <xsl:variable name="sz">
-      <xsl:choose>
-        <xsl:when test="$type='f' and (@s&lt;1 or @t&lt;0)"><xsl:value-of select="$szBase+3"/></xsl:when>
-        <xsl:when test="@l&lt;0"><xsl:value-of select="$szBase+1"/></xsl:when>
-        <xsl:otherwise><xsl:value-of select="$szBase"/></xsl:otherwise>
-      </xsl:choose>
-    </xsl:variable>
-    <xsl:choose>
-      <xsl:when test="$ln>=10000 and $ln&lt;=1000"><!-- disabled in pactice, with a large value -->
-        <xsl:element name="input">
-          <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="type">text</xsl:attribute>
-          <xsl:attribute name="class">slider ledField</xsl:attribute>
-          <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-          <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-          <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-          <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-          <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-          <!-- <xsl:attribute name="data-src"><xsl:value-of select="$path"/></xsl:attribute> -->
-          <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-        </xsl:element>
-        <!-- some fancy slider.. not working yet -->
-        <!-- <xsl:element name="input">
-          <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="data-slider-id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="type">text</xsl:attribute>
-          <xsl:attribute name="data-slider-min"><xsl:value-of select="@l"/></xsl:attribute>
-          <xsl:attribute name="data-slider-max"><xsl:value-of select="@h"/></xsl:attribute>
-          <xsl:attribute name="data-slider-step"><xsl:value-of select="@t"/></xsl:attribute>
-          <xsl:attribute name="data-slider-value"><xsl:apply-templates/></xsl:attribute>
-        </xsl:element> -->
-        <!-- standard slider -->
-        <!-- <xsl:element name="input">
-          <xsl:copy-of select="node/@*"/>
-          <xsl:copy-of select="../../p/@i"/>
-          <xsl:attribute name="class">menu-range-fld</xsl:attribute>
-          <xsl:attribute name="type">range</xsl:attribute>
-          <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-          <xsl:attribute name="data-src"><xsl:value-of select="$at"/></xsl:attribute>
-          <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-        </xsl:element> -->
-      </xsl:when>
-      <xsl:otherwise>
-      <xsl:element name="input">
-          <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../@i"/></xsl:attribute>
-          <xsl:attribute name="type">text</xsl:attribute>
-          <xsl:attribute name="size"><xsl:value-of select="$sz"/></xsl:attribute>
-          <xsl:if test="$sz&lt;8">
-            <xsl:attribute name="maxlength"><xsl:value-of select="$sz"/></xsl:attribute>
-          </xsl:if>
-          <xsl:attribute name="value"><xsl:apply-templates/></xsl:attribute>
-          <xsl:attribute name="class">form-control</xsl:attribute>
-          <xsl:attribute name="data-src"><xsl:value-of select="$at"/></xsl:attribute>
-          <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-        </xsl:element>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:template>
-
-  <xsl:template match="select|choose">
-    <xsl:apply-templates select="node"/>
-  </xsl:template>
-
-  <xsl:template match="node">
-    <xsl:element name="select">
-      <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../../../p/@i"/></xsl:attribute>
-      <xsl:attribute name="class">form-control</xsl:attribute>
-      <xsl:attribute name="data-src"><xsl:value-of select="../../../../@r"/>/<xsl:value-of select="../../../@i"/></xsl:attribute>
-      <xsl:attribute name="onchange">window.location.href='/menu?at='+getAttribute('data-src')+'/'+selectedIndex</xsl:attribute>
-      <xsl:apply-templates/>
-    </xsl:element>
-  </xsl:template>
-
-  <xsl:template match="node/value">
-    <xsl:element name="option">
-      <xsl:copy-of select="@*"/>
-      <xsl:apply-templates/>
-    </xsl:element>
-  </xsl:template>
-
-  <xsl:template match="fv[../p[@t='textField']]">
-    <xsl:element name="input">
-    <xsl:attribute name="id">fld_<xsl:value-of select="/menuLib/panel/@id"/>_<xsl:value-of select="../p/@i"/></xsl:attribute>
-    <xsl:attribute name="value"><xsl:value-of select="."/></xsl:attribute>
-    <xsl:attribute name="class">form-control</xsl:attribute>
-    <xsl:attribute name="data-src"><xsl:value-of select="../../../@r"/>/<xsl:value-of select="../../@i"/></xsl:attribute>
-    <xsl:attribute name="onchange">window.location='/menu?at='+getAttribute("data-src")+'/'+value</xsl:attribute>
-    </xsl:element>
-  </xsl:template>
-
-</xsl:stylesheet>
diff --git a/examples/esp8266/WebMenu/WebMenu/data/1.5/device.xslt b/examples/esp8266/WebMenu/WebMenu/data/1.5/device.xslt
deleted file mode 100644
index 479057a7..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/1.5/device.xslt
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
-  <!-- <xsl:output method="html" encoding="utf-8" indent="yes" /> -->
-
-  <xsl:include href="menu.xslt"/>
-  <xsl:include href="bootstrap.xslt"/>
-
-  <!-- put here device specifics translations, if any ////////////////////// -->
-
-</xsl:stylesheet>
diff --git a/examples/esp8266/WebMenu/WebMenu/data/1.5/index.html b/examples/esp8266/WebMenu/WebMenu/data/1.5/index.html
deleted file mode 100644
index 5fbda736..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/1.5/index.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head profile="http://www.w3.org/2005/10/profile">
-  <meta charset="utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
-  <meta name="description" content="ArduinoMenu Example IOT/OTA for ESP8266">
-  <meta name="author" content="Rui Azevedo <ruihfazevedo@gmail.com> (www.r-site.net)">
-  <title>ArduinoMenu library OTA</title>
-  <link rel="icon" type="image/png" href="/logo.png">
-  <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha256-/SIrNqv8h6QGKDuNoLGA4iret+kyesCkHGzVUUV0shc=" crossorigin="anonymous"></script>
-  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
-  <!--[if lt IE 9]>
-    <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
-    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
-  <![endif]-->
-  <!--link rel="stylesheet" type="text/css" href="/r-site.css"-->
-  <link rel="stylesheet" type="text/css" href="menu.css">
-  <script type="text/javascript" src="r-site.js" ></script>
-</head>
-<body class="ArduinoMenu">
-  <div class="site-wrapper">
-
-    <div class="site-wrapper-inner">
-
-      <div class="cover-container">
-
-        <div class="masthead clearfix">
-          <div class="inner">
-            <h3 class="masthead-brand">ArduinoMenu library</h3>
-            <nav>
-              <ul class="nav masthead-nav">
-                <li class="active"><a href="/" id="start">Home</a></li>
-                <li><a href="/menu?at=/" id="menu">Menu</a></li>
-                <li><a href="https://github.com/neu-rah/ArduinoMenu">Repo</a></li>
-                <!--li><a href="#">Features</a></li-->
-                <li><a href="http://www.r-site.net/site/struct.asp?at=//menu[@id=%27main%27]/*[5]">Contact</a></li>
-              </ul>
-            </nav>
-          </div>
-        </div>
-
-        <div class="inner cover">
-          <h2><img src="/img/logo.png" height="48px"/>on ESP8266</h1>
-          <p>Example of async menu call on customized static web page.</p>
-            <a href="/?at=/1" class="btn btn-lg btn-success">Action A</a>
-            <a href="/?at=/2" class="btn btn-lg btn-default">Action B</a>
-            <a href="/menu" class="btn btn-lg">Full menu</a>
-        </div>
-        <hr/>
-        <p>This example just uses regular links to call menu actions, no feedback is provided on this mode.</p>
-        <p>To have some feedback and iteraction use the full menu page.</p>
-
-        <div class="mastfoot">
-          <div class="inner">
-            <p>ArduinoMenu library <a href="https://github.com/neu-rah/ArduinoMenu">https://github.com/neu-rah/ArduinoMenu</a>.</p>
-          </div>
-        </div>
-
-      </div>
-
-    </div>
-
-  </div>
-
-</body></html>
diff --git a/examples/esp8266/WebMenu/WebMenu/data/1.5/menu.css b/examples/esp8266/WebMenu/WebMenu/data/1.5/menu.css
deleted file mode 100644
index b5b9b91a..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/1.5/menu.css
+++ /dev/null
@@ -1,302 +0,0 @@
-html,
-body {
-  height: 100%;
-  background-color: #1d80e2;
-}
-body {
-  color: #fff;
-  text-align: center;
-  text-shadow: 0 1px 3px rgba(0,0,0,.5);
-  font-size: 18px;
-}
-
-#outDlg .modal-content, .upForm {
-  background-color: #888 !important;
-  padding:1em;
-}
-
-/* .masthead {
-  background-image: url(nav-bg.jpg);
-  background-size: cover;
-  background-position: center;
-} */
-
-nav {
-  background-color: #333;
-}
-
-a {
-  text-decoration: none !important;
-}
-
-input, select {
-  width: auto;
-  color: yellow;
-  background-color: transparent;
-  /* border: none; */
-}
-
-input[@type="uint32_t"] {
-  text-align: right;
-}
-
-/* Links */
-a,
-a:focus,
-a:hover {
-  color: #fff;
-}
-
-/* .asPad {background-color: gray;} */
-.pad-item {display: inline-block !important;}
-
-.form-control {
-  width:auto;
-  display:inline-block;
-}
-
-.aml_op.btn {width:100%;}
-
-.actionBtn {
-  display:inline-block;
-  padding:1em;
-  background-color: #0ba6a4;
-  color: lime;
-  border: solid 1px lime;
-  border-radius: 3px;
-  text-align: right;
-}
-
-/* Custom default button */
-.btn-default,
-.btn-default:hover,
-.btn-default:focus {
-  color: #333;
-  text-shadow: none; /* Prevent inheritance from `body` */
-  background-color: #fff;
-  border: 1px solid #fff;
-}
-
-input[type=range] {
-  display:inline-block !important;
-  width:auto !important;
-  background-color:#000800;
-}
-
-/*
- * Base structure
- */
-
-select {color: black;}
-
-/* Extra markup and styles for table-esque vertical and horizontal centering */
-.site-wrapper {
-  display: table;
-  width: 100%;
-  height: 100%; /* For at least Firefox */
-  min-height: 100%;
-  -webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-          box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-}
-.site-wrapper-inner {
-  display: table-cell;
-  vertical-align: top;
-}
-.cover-container {
-  margin-right: auto;
-  margin-left: auto;
-}
-
-/* Padding for spacing */
-/* .inner {
-  padding: 30px;
-} */
-
-
-/*
- * Header
- */
-.masthead{
-	background-color: #1d80e2;
-	height:150px;
-  overflow:hidden;
-  z-index:100;
-}
-/* .masthead-brand {
-  margin-top: 0px !important;
-} */
-.masthead .wrap{
-	-webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-    box-shadow: inset 0 0 100px rgba(0,0,0,.5);
-	height:200px;
-}
-
-.masthead .inner{
-	/* padding:0 20px 0 60px; */
-}
-
-.masthead-brand {
-  margin-top: 0px;
-  padding-top: 0.5em;
-  margin-bottom: 0em;
-}
-
-ul {
-  list-style-type: none;
-}
-
-.masthead-nav > li {
-  display: inline-block;
-}
-.masthead-nav > li + li {
-  margin-left: 0.5em;
-}
-.masthead-nav > li > a {
-  padding-right: 0;
-  padding-left: 0;
-  font-size: 16px;
-  font-weight: bold;
-  color: #fff; /* IE8 proofing */
-  color: rgba(255,255,255,.75);
-  border-bottom: 2px solid transparent;
-}
-.masthead-nav > li > a:hover,
-.masthead-nav > li > a:focus {
-  background-color: transparent;
-  border-bottom-color: #a9a9a9;
-  border-bottom-color: rgba(255,255,255,.25);
-}
-.masthead-nav > .active > a,
-.masthead-nav > .active > a:hover,
-.masthead-nav > .active > a:focus {
-  color: #fff;
-  border-bottom-color: #fff;
-}
-
-@media (min-width: 768px) {
-  .masthead{
-  	height:100px;
-  }
-  .masthead-brand {
-    float: left;
-  }
-  .masthead-nav {
-  margin-top: 1em;
-    float: right;
-  }
-}
-
-/*
- * Cover
- */
-
-.cover .btn-lg {
-  /* padding: 10px 20px; */
-  font-weight: bold;
-}
-
-.cover .btn-lg.linkBtn>a {
-  padding: 10px 20px;
-}
-
-/*
- * Footer
- */
-
-.mastfoot {
-  font-size: 0.6em;
-  color: #999; /* IE8 proofing */
-  color: rgba(255,255,255,.5);
-  /* z-index: -1; */
-}
-
-
-/*
- * Affix and center
- */
-
-@media (min-width: 768px) {
-  /* Pull out the header and footer */
-  .masthead {
-    position: fixed;
-    top: 0;
-	  left: 0;
-  }
-  .mastfoot {
-    position: fixed;
-    bottom: 0;
-  }
-  /* Start the vertical centering */
-  .site-wrapper-inner {
-    vertical-align: middle;
-  }
-  /* Handle the widths */
-  .masthead,
-  .mastfoot,
-  .cover-container {
-    width: 100%; /* Must be percentage or pixels for horizontal alignment */
-  }
-  .cover-container {
-    width: 700px;
-  }
-  .cover {
-    padding: 100px 1em 1em 1em !important;
-  }
-
-}
-
-@media (min-width: 992px) {
-  .masterhead {
-    padding: 1em;
-  }
-  .masthead .inner{
-	   margin: 0 auto;
-  }
-  .masthead .inner,
-  .mastfoot,
-  .cover-container {
-    width: 700px;
-  }
-  .cover {
-    padding: 100px 1em 1em 1em !important;
-  }
-}
-
-.btn-active {
-  color: #fff;
-  background-color: #333;
-  border-color: #d58512;
-}
-
-.btn-disabled {
-  color: #fff;
-  background-color: #696969;
-  border-color: #4cae4c;
-}
-
-.slider {
-  margin-right:1em;
-  margin-left: 1em;
-}
-
-.slider-selection {
-	background: #BABABA;
-}
-
-.slider.slider-horizontal {
-  width:20% !important;
-}
-
-.aml_op .del {
-  color:red;
-}
-
-div.padOp {display:inline-block;}
-
-li.linkBtn {padding:0;}
-li.linkBtn>a {display:block;margin:0;}
-
-.btn-space {
-  padding-left:0.5em;
-  padding-right:0.5em;
-}
diff --git a/examples/esp8266/WebMenu/WebMenu/data/1.5/menu.xslt b/examples/esp8266/WebMenu/WebMenu/data/1.5/menu.xslt
deleted file mode 100644
index 17884ad6..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/1.5/menu.xslt
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-	xmlns:dyn="http://r-site.net"
-	xmlns:msxsl="urn:schemas-microsoft-com:xslt"
-	extension-element-prefixes="dyn msxsl">
-
-  <!-- you can host aux files on external server
-    if it is the case set this variable to the server address:port
-    this is usefull for develop/debug
-    to use external server the browser must be intructed to accept cross domain files
-  -->
-  <!-- <xsl:variable name="auxFilesSrc"></xsl:variable> -->
-  <xsl:variable name="auxFilesSrc">
-    <xsl:choose>
-      <xsl:when test="/menuLib/@debug='yes'">http://neurux:8080/</xsl:when>
-      <xsl:otherwise></xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-
-  <xsl:template match="/">
-    <html>
-      <head>
-        <meta charset="utf-8"/>
-        <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
-        <meta name="viewport" content="width=device-width, initial-scale=1"/>
-        <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
-        <meta name="description" content="ArduinoMenu Library auto generated web menu"/>
-        <meta name="author" content="Rui Azevedo ruihfazevedo@gmail.com (https://github.com/neu-rah)"/>
-        <title>ArduinoMenu&lt;web&gt;</title>
-        <!-- <script src="{$auxFilesSrc}/jquery-3.3.1.min.js"></script> -->
-        <script
-          src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
-          integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E="
-          crossorigin="anonymous"></script>
-
-        <!-- Latest compiled and minified CSS -->
-        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"/>
-
-        <!-- Optional theme -->
-        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"/>
-
-        <!-- Latest compiled and minified JavaScript -->
-        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-
-        <!-- <link href="{$auxFilesSrc}/bootstrap.min.css" rel="stylesheet"/>
-        <script src="{$auxFilesSrc}/bootstrap.min.js"></script> -->
-        <link href="{$auxFilesSrc}/bootstrap-slider.min.css" rel="stylesheet"/>
-        <script src="{$auxFilesSrc}/bootstrap-slider.min.js"></script>
-        <link rel="stylesheet" type="text/css" href="{$auxFilesSrc}/{/menuLib/sourceURL/@ver}menu.css"/>
-        <script src="{$auxFilesSrc}/{/menuLib/sourceURL/@ver}r-site.js"></script>
-        <link rel="icon" type="image/png" href="/img/icon.png"/>
-      </head>
-      <body class="ArduinoMenu">
-        <div class="site-wrapper">
-          <div class="site-wrapper-inner">
-            <div class="cover-container">
-              <div class="masthead clearfix">
-                <div class="wrap">
-                <div class="inner">
-                  <h1 class="masthead-brand">
-                    <a href="http://r-site.net/" target="_blank"><img src="/img/logo.png" height="72px" alt="r-site.net"/></a>
-        				  </h1>
-                          <nav>
-                            <ul class="nav masthead-nav">
-                              <li><a href="/" id="start">Home</a></li>
-                              <li class="active"><a href="/menu?at=/" id="menu">Menu</a></li>
-                              <li><a href="https://github.com/neu-rah/ArduinoMenu" id="repo" target="_blank">Repo</a></li>
-                              <li><a href="http://www.r-site.net/site/struct.asp?at=//menu[@id=%27main%27]/*[5]" id="contact" target="_blank">Contact</a></li>
-                            </ul>
-                          </nav>
-                </div>
-                </div>
-              </div>
-              <div class="inner cover">
-                <xsl:apply-templates/>
-              </div>
-
-              <div class="mastfoot">
-                <div class="inner">
-                  <p>ArduinoMenu library <a href="https://github.com/neu-rah/ArduinoMenu">https://github.com/neu-rah/ArduinoMenu</a>.</p>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </body>
-    </html>
-  </xsl:template>
-
-</xsl:stylesheet>
diff --git a/examples/esp8266/WebMenu/WebMenu/data/1.5/r-site.js b/examples/esp8266/WebMenu/WebMenu/data/1.5/r-site.js
deleted file mode 100644
index 9e948659..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/1.5/r-site.js
+++ /dev/null
@@ -1,176 +0,0 @@
-// wsSrc = sourceURL;
-wsSrc=window.location.hostname;
-var connection = {};
-
-// alert("r-site.js loaded!");
-var lastResult=null;
-var previousResult=null;
-
-function connectWS() {
-  console.log("ws://" + wsSrc + ":81/", ["arduino"]);
-  connection = new WebSocket("ws://" + wsSrc + ":81/", ["arduino"]);
-  connection.onopen = init;
-  connection.onerror = function(e) {console.log("WebSocket Error ", e)};
-  connection.onmessage = function(e) {
-    try {
-      console.log(JSON.parse(e.data));//just for checking it
-    } catch(err) {
-      console.log("NO JSON!",e.data);
-    }
-    eval("lastResult="+e.data);
-    //updatePage();
-  };
-  return connection.readyState;
-}
-
-function updatePage() {
-  if (lastResult) mkPath(lastResult);//add path info
-  if (lastResult==previousResult) return;
-  if (previousResult&&lastResult.menu.title.prompt===previousResult.menu.title.prompt)
-      walkStates(lastResult.menu,previousResult.menu);
-  previousResult=lastResult;
-}
-
-function refreshBtn(_,o) {
-  var p=$(o).attr("data-src");
-  var g=$(o).attr("data-grp");
-  var nv=jpath(g,lastResult.menu);
-  if (nv.value==$(o).text())
-    console.log(p,g,nv);
-}
-
-//get a single value out a menu state page by path
-//it matches the page postion and selects requested item
-//so path is absolute
-function jpath(p,m) {
-  if (m.path!=p.slice(0,m.path.length)) return;
-  var ps=p.slice(m.path.length).split("/").slice(1);
-  return _jpath(m,ps);
-  function _jpath(m,o) {
-    var i=(m.pad||m.items)
-    if (!i&&o.length>0) return;
-    return (o.length&&i)?_jpath(i[o[0]],o.slice(1)):m
-  }
-}
-
-//traverses previous and last state and
-//update controls of changed values
-function walkStates(i,j) {
-  if(!(i&&j)) return;
-  // console.log("walking states...");
-  if (i.path!=j.path) return;
-  // console.log("path",i.path);
-  if (i.field&&j.field&&i.field!=j.field) {//numeric field!
-    var target=$("[data-src='"+i.path+"'");
-    if (target.length) {
-      console.log("setting new field",i.path,i.field,target);
-      if (target.hasClass("slider")) target.slider("setValue",i.field);
-      else target.val(i.field);
-    }
-  } if (i.options&&j.options&&i.value!=j.value) {//enumerated field
-    var nvi=i.options.indexOf(i.value);
-    console.log("looking for",i.path);
-    var target=$("[data-src='"+i.path+"/"+nvi+"']");
-    if (target.length) {
-      console.log("clicking on button");
-      target.click();
-    } else {
-      target=$("select[data-src='"+i.path+"']");
-      if (target.length) {
-        console.log("changing selection",i.path,i.select);
-        target.val(i.select);
-      }
-
-    }
-  }
-  if (typeof i[Symbol.iterator] === 'function'&&typeof j[Symbol.iterator] === 'function')
-    for(var n=0;n<i.length;n++)
-      walkStates(i[n],j[n]);
-  if(i.pad) walkStates(i.pad,j.pad)
-  if(i.items) walkStates(i.items,j.items)
-}
-
-function mkPath(m) {
-  if (m.menu) _mkPath(m.menu.items,m.menu.path||"")
-  function _mkPath(i,path) {
-    // console.log("_mkPath:",path,i);
-    if (i.idx) i.path=path+"/"+i.idx;
-    if (typeof i[Symbol.iterator] === 'function')
-      for(n of i)
-        _mkPath(n,i.path||path);
-    if(i.pad) _mkPath(i.pad,i.path||path)
-  }
-}
-
-function menu(o,cnt) {
-  if(connection.readyState!=1) {//not connected (yet)?
-    console.log("not connected yet...")
-    if (connection.readyState==3) {//disconnected?
-      console.log("connecting websocket");
-      connectWS();
-    }
-    setTimeout(function() {//check latter...
-      console.log("checking websocket connetion");
-      if (connection.readyState!=1&&cnt>5) {//give up?
-        alert("websocket disconnected, please refresh page");//TODO: put mutilang here
-        return;
-      } else menu(o,cnt?cnt+1:0);
-    },500);
-    return;
-  }
-  console.log("send ws",o);
-  return connection.send(o);
-}
-
-function updateField(e) {
-  return updateField_(e.target)
-}
-
-function updateField_(e) {
-  var n = $(e).attr("data-src") + "/" + e.value + String.fromCharCode(255);
-  menu(n);
-}
-
-function updateLink(e) {
-  return updateLink_(e.target)
-}
-
-function updateLink_(e) {
-  var n = $(e),
-    o = n.attr("data-grp"),
-    t = n.attr("data-src");
-  // console.log("removing selections");
-  $("a[data-grp='" + o + "']").removeClass("btn-primary btn-success");
-  // console.log("adding selection to", e);
-  n.addClass("btn-primary");
-  // console.log("sending: " + t);
-  menu(t);
-  // connection.send(t)
-}
-
-function updateSelect(e) {
-  updateSelect_(e.target)
-}
-
-function updateSelect_(e) {
-  var n = $(e).attr("data-src") + "/" + e.selectedIndex;
-  // console.log("sending: " + n);
-  menu(n);
-  // connection.send(n);
-}
-
-function init() {
-  console.log("menu websocket server connected.");
-  console.log("r-site menu page script starting.");
-  activePanel = $(".aml_panel");
-  $(".aml_op>input").removeAttr("onchange").off("change").on("change", updateField);
-  $(".aml_op>select").removeAttr("onchange").off("change").on("change", updateSelect);
-  $("a.aml_btn").removeAttr("href").off("click").on("click", updateLink);
-  // $(".aml_op input.ledField").removeAttr("onchange").off("change").on("change", logField);
-}
-$(function() {
-  // console.log("ready!");
-  connectWS();
-  $("p.out").text() && $("#outDlg").modal();
-  jQuery().slider && $(".slider").slider({formatter: function(e) {return e + "%"}});
-});
diff --git a/examples/esp8266/WebMenu/WebMenu/data/bootstrap-slider.min.css b/examples/esp8266/WebMenu/WebMenu/data/bootstrap-slider.min.css
deleted file mode 100644
index c0234bfd..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/bootstrap-slider.min.css
+++ /dev/null
@@ -1,41 +0,0 @@
-/*! =======================================================
-                      VERSION  10.0.0
-========================================================= */
-/*! =========================================================
- * bootstrap-slider.js
- *
- * Maintainers:
- *		Kyle Kemp
- *			- Twitter: @seiyria
- *			- Github:  seiyria
- *		Rohit Kalkur
- *			- Twitter: @Rovolutionary
- *			- Github:  rovolution
- *
- * =========================================================
-  *
- * bootstrap-slider is released under the MIT License
- * Copyright (c) 2017 Kyle Kemp, Rohit Kalkur, and contributors
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * ========================================================= */.slider{display:inline-block;vertical-align:middle;position:relative}.slider.slider-horizontal{width:210px;height:20px}.slider.slider-horizontal .slider-track{height:10px;width:100%;margin-top:-5px;top:50%;left:0}.slider.slider-horizontal .slider-selection,.slider.slider-horizontal .slider-track-low,.slider.slider-horizontal .slider-track-high{height:100%;top:0;bottom:0}.slider.slider-horizontal .slider-tick,.slider.slider-horizontal .slider-handle{margin-left:-10px}.slider.slider-horizontal .slider-tick.triangle,.slider.slider-horizontal .slider-handle.triangle{position:relative;top:50%;-ms-transform:translateY(-50%);transform:translateY(-50%);border-width:0 10px 10px 10px;width:0;height:0;border-bottom-color:#2e6da4;margin-top:0}.slider.slider-horizontal .slider-tick-container{white-space:nowrap;position:absolute;top:0;left:0;width:100%}.slider.slider-horizontal .slider-tick-label-container{white-space:nowrap;margin-top:20px}.slider.slider-horizontal .slider-tick-label-container .slider-tick-label{padding-top:4px;display:inline-block;text-align:center}.slider.slider-horizontal .tooltip{-ms-transform:translateX(-50%);transform:translateX(-50%)}.slider.slider-horizontal.slider-rtl .slider-track{left:initial;right:0}.slider.slider-horizontal.slider-rtl .slider-tick,.slider.slider-horizontal.slider-rtl .slider-handle{margin-left:initial;margin-right:-10px}.slider.slider-horizontal.slider-rtl .slider-tick-container{left:initial;right:0}.slider.slider-horizontal.slider-rtl .tooltip{-ms-transform:translateX(50%);transform:translateX(50%)}.slider.slider-vertical{height:210px;width:20px}.slider.slider-vertical .slider-track{width:10px;height:100%;left:25%;top:0}.slider.slider-vertical .slider-selection{width:100%;left:0;top:0;bottom:0}.slider.slider-vertical .slider-track-low,.slider.slider-vertical .slider-track-high{width:100%;left:0;right:0}.slider.slider-vertical .slider-tick,.slider.slider-vertical .slider-handle{margin-top:-10px}.slider.slider-vertical .slider-tick.triangle,.slider.slider-vertical .slider-handle.triangle{border-width:10px 0 10px 10px;width:1px;height:1px;border-left-color:#2e6da4;border-right-color:#2e6da4;margin-left:0;margin-right:0}.slider.slider-vertical .slider-tick-label-container{white-space:nowrap}.slider.slider-vertical .slider-tick-label-container .slider-tick-label{padding-left:4px}.slider.slider-vertical .tooltip{-ms-transform:translateY(-50%);transform:translateY(-50%)}.slider.slider-vertical.slider-rtl .slider-track{left:initial;right:25%}.slider.slider-vertical.slider-rtl .slider-selection{left:initial;right:0}.slider.slider-vertical.slider-rtl .slider-tick.triangle,.slider.slider-vertical.slider-rtl .slider-handle.triangle{border-width:10px 10px 10px 0}.slider.slider-vertical.slider-rtl .slider-tick-label-container .slider-tick-label{padding-left:initial;padding-right:4px}.slider.slider-disabled .slider-handle{background-image:-webkit-linear-gradient(top,#dfdfdf 0,#bebebe 100%);background-image:-o-linear-gradient(top,#dfdfdf 0,#bebebe 100%);background-image:linear-gradient(to bottom,#dfdfdf 0,#bebebe 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdfdfdf',endColorstr='#ffbebebe',GradientType=0)}.slider.slider-disabled .slider-track{background-image:-webkit-linear-gradient(top,#e5e5e5 0,#e9e9e9 100%);background-image:-o-linear-gradient(top,#e5e5e5 0,#e9e9e9 100%);background-image:linear-gradient(to bottom,#e5e5e5 0,#e9e9e9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe5e5e5',endColorstr='#ffe9e9e9',GradientType=0);cursor:not-allowed}.slider input{display:none}.slider .tooltip.top{margin-top:-36px}.slider .tooltip-inner{white-space:nowrap;max-width:none}.slider .hide{display:none}.slider-track{position:absolute;cursor:pointer;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#f9f9f9 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#f9f9f9 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#f9f9f9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);border-radius:4px}.slider-selection{position:absolute;background-image:-webkit-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#f9f9f9 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:4px}.slider-selection.tick-slider-selection{background-image:-webkit-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:-o-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:linear-gradient(to bottom,#8ac1ef 0,#82b3de 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8ac1ef',endColorstr='#ff82b3de',GradientType=0)}.slider-track-low,.slider-track-high{position:absolute;background:transparent;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:4px}.slider-handle{position:absolute;top:0;width:20px;height:20px;background-color:#337ab7;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7',endColorstr='#ff2e6da4',GradientType=0);filter:none;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);border:0 solid transparent}.slider-handle.round{border-radius:50%}.slider-handle.triangle{background:transparent none}.slider-handle.custom{background:transparent none}.slider-handle.custom::before{line-height:20px;font-size:20px;content:'\2605';color:#726204}.slider-tick{position:absolute;width:20px;height:20px;background-image:-webkit-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#f9f9f9 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#f9f9f9 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;filter:none;opacity:.8;border:0 solid transparent}.slider-tick.round{border-radius:50%}.slider-tick.triangle{background:transparent none}.slider-tick.custom{background:transparent none}.slider-tick.custom::before{line-height:20px;font-size:20px;content:'\2605';color:#726204}.slider-tick.in-selection{background-image:-webkit-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:-o-linear-gradient(top,#8ac1ef 0,#82b3de 100%);background-image:linear-gradient(to bottom,#8ac1ef 0,#82b3de 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8ac1ef',endColorstr='#ff82b3de',GradientType=0);opacity:1}
diff --git a/examples/esp8266/WebMenu/WebMenu/data/bootstrap-slider.min.js b/examples/esp8266/WebMenu/WebMenu/data/bootstrap-slider.min.js
deleted file mode 100644
index bd11ca85..00000000
--- a/examples/esp8266/WebMenu/WebMenu/data/bootstrap-slider.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*! =======================================================
-                      VERSION  10.0.0
-========================================================= */
-"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},windowIsDefined="object"===("undefined"==typeof window?"undefined":_typeof(window));!function(a){if("function"==typeof define&&define.amd)define(["jquery"],a);else if("object"===("undefined"==typeof module?"undefined":_typeof(module))&&module.exports){var b;try{b=require("jquery")}catch(c){b=null}module.exports=a(b)}else window&&(window.Slider=a(window.jQuery))}(function(a){var b="slider",c="bootstrapSlider";windowIsDefined&&!window.console&&(window.console={}),windowIsDefined&&!window.console.log&&(window.console.log=function(){}),windowIsDefined&&!window.console.warn&&(window.console.warn=function(){});var d;return function(a){function b(){}function c(a){function c(b){b.prototype.option||(b.prototype.option=function(b){a.isPlainObject(b)&&(this.options=a.extend(!0,this.options,b))})}function e(b,c){a.fn[b]=function(e){if("string"==typeof e){for(var g=d.call(arguments,1),h=0,i=this.length;i>h;h++){var j=this[h],k=a.data(j,b);if(k)if(a.isFunction(k[e])&&"_"!==e.charAt(0)){var l=k[e].apply(k,g);if(void 0!==l&&l!==k)return l}else f("no such method '"+e+"' for "+b+" instance");else f("cannot call methods on "+b+" prior to initialization; attempted to call '"+e+"'")}return this}var m=this.map(function(){var d=a.data(this,b);return d?(d.option(e),d._init()):(d=new c(this,e),a.data(this,b,d)),a(this)});return!m||m.length>1?m:m[0]}}if(a){var f="undefined"==typeof console?b:function(a){console.error(a)};return a.bridget=function(a,b){c(b),e(a,b)},a.bridget}}var d=Array.prototype.slice;c(a)}(a),function(a){function e(b,c){function d(a,b){var c="data-slider-"+b.replace(/_/g,"-"),d=a.getAttribute(c);try{return JSON.parse(d)}catch(e){return d}}this._state={value:null,enabled:null,offset:null,size:null,percentage:null,inDrag:!1,over:!1},this.ticksCallbackMap={},this.handleCallbackMap={},"string"==typeof b?this.element=document.querySelector(b):b instanceof HTMLElement&&(this.element=b),c=c?c:{};for(var e=Object.keys(this.defaultOptions),f=0;f<e.length;f++){var h=e[f],i=c[h];i="undefined"!=typeof i?i:d(this.element,h),i=null!==i?i:this.defaultOptions[h],this.options||(this.options={}),this.options[h]=i}"auto"===this.options.rtl&&(this.options.rtl="rtl"===window.getComputedStyle(this.element).direction),"vertical"!==this.options.orientation||"top"!==this.options.tooltip_position&&"bottom"!==this.options.tooltip_position?"horizontal"!==this.options.orientation||"left"!==this.options.tooltip_position&&"right"!==this.options.tooltip_position||(this.options.tooltip_position="top"):this.options.rtl?this.options.tooltip_position="left":this.options.tooltip_position="right";var j,k,l,m,n,o=this.element.style.width,p=!1,q=this.element.parentNode;if(this.sliderElem)p=!0;else{this.sliderElem=document.createElement("div"),this.sliderElem.className="slider";var r=document.createElement("div");r.className="slider-track",k=document.createElement("div"),k.className="slider-track-low",j=document.createElement("div"),j.className="slider-selection",l=document.createElement("div"),l.className="slider-track-high",m=document.createElement("div"),m.className="slider-handle min-slider-handle",m.setAttribute("role","slider"),m.setAttribute("aria-valuemin",this.options.min),m.setAttribute("aria-valuemax",this.options.max),n=document.createElement("div"),n.className="slider-handle max-slider-handle",n.setAttribute("role","slider"),n.setAttribute("aria-valuemin",this.options.min),n.setAttribute("aria-valuemax",this.options.max),r.appendChild(k),r.appendChild(j),r.appendChild(l),this.rangeHighlightElements=[];var s=this.options.rangeHighlights;if(Array.isArray(s)&&s.length>0)for(var t=0;t<s.length;t++){var u=document.createElement("div"),v=s[t]["class"]||"";u.className="slider-rangeHighlight slider-selection "+v,this.rangeHighlightElements.push(u),r.appendChild(u)}var w=Array.isArray(this.options.labelledby);if(w&&this.options.labelledby[0]&&m.setAttribute("aria-labelledby",this.options.labelledby[0]),w&&this.options.labelledby[1]&&n.setAttribute("aria-labelledby",this.options.labelledby[1]),!w&&this.options.labelledby&&(m.setAttribute("aria-labelledby",this.options.labelledby),n.setAttribute("aria-labelledby",this.options.labelledby)),this.ticks=[],Array.isArray(this.options.ticks)&&this.options.ticks.length>0){for(this.ticksContainer=document.createElement("div"),this.ticksContainer.className="slider-tick-container",f=0;f<this.options.ticks.length;f++){var x=document.createElement("div");if(x.className="slider-tick",this.options.ticks_tooltip){var y=this._addTickListener(),z=y.addMouseEnter(this,x,f),A=y.addMouseLeave(this,x);this.ticksCallbackMap[f]={mouseEnter:z,mouseLeave:A}}this.ticks.push(x),this.ticksContainer.appendChild(x)}j.className+=" tick-slider-selection"}if(this.tickLabels=[],Array.isArray(this.options.ticks_labels)&&this.options.ticks_labels.length>0)for(this.tickLabelContainer=document.createElement("div"),this.tickLabelContainer.className="slider-tick-label-container",f=0;f<this.options.ticks_labels.length;f++){var B=document.createElement("div"),C=0===this.options.ticks_positions.length,D=this.options.reversed&&C?this.options.ticks_labels.length-(f+1):f;B.className="slider-tick-label",B.innerHTML=this.options.ticks_labels[D],this.tickLabels.push(B),this.tickLabelContainer.appendChild(B)}var E=function(a){var b=document.createElement("div");b.className="tooltip-arrow";var c=document.createElement("div");c.className="tooltip-inner",a.appendChild(b),a.appendChild(c)},F=document.createElement("div");F.className="tooltip tooltip-main",F.setAttribute("role","presentation"),E(F);var G=document.createElement("div");G.className="tooltip tooltip-min",G.setAttribute("role","presentation"),E(G);var H=document.createElement("div");H.className="tooltip tooltip-max",H.setAttribute("role","presentation"),E(H),this.sliderElem.appendChild(r),this.sliderElem.appendChild(F),this.sliderElem.appendChild(G),this.sliderElem.appendChild(H),this.tickLabelContainer&&this.sliderElem.appendChild(this.tickLabelContainer),this.ticksContainer&&this.sliderElem.appendChild(this.ticksContainer),this.sliderElem.appendChild(m),this.sliderElem.appendChild(n),q.insertBefore(this.sliderElem,this.element),this.element.style.display="none"}if(a&&(this.$element=a(this.element),this.$sliderElem=a(this.sliderElem)),this.eventToCallbackMap={},this.sliderElem.id=this.options.id,this.touchCapable="ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,this.touchX=0,this.touchY=0,this.tooltip=this.sliderElem.querySelector(".tooltip-main"),this.tooltipInner=this.tooltip.querySelector(".tooltip-inner"),this.tooltip_min=this.sliderElem.querySelector(".tooltip-min"),this.tooltipInner_min=this.tooltip_min.querySelector(".tooltip-inner"),this.tooltip_max=this.sliderElem.querySelector(".tooltip-max"),this.tooltipInner_max=this.tooltip_max.querySelector(".tooltip-inner"),g[this.options.scale]&&(this.options.scale=g[this.options.scale]),p===!0&&(this._removeClass(this.sliderElem,"slider-horizontal"),this._removeClass(this.sliderElem,"slider-vertical"),this._removeClass(this.sliderElem,"slider-rtl"),this._removeClass(this.tooltip,"hide"),this._removeClass(this.tooltip_min,"hide"),this._removeClass(this.tooltip_max,"hide"),["left","right","top","width","height"].forEach(function(a){this._removeProperty(this.trackLow,a),this._removeProperty(this.trackSelection,a),this._removeProperty(this.trackHigh,a)},this),[this.handle1,this.handle2].forEach(function(a){this._removeProperty(a,"left"),this._removeProperty(a,"right"),this._removeProperty(a,"top")},this),[this.tooltip,this.tooltip_min,this.tooltip_max].forEach(function(a){this._removeProperty(a,"left"),this._removeProperty(a,"right"),this._removeProperty(a,"top"),this._removeClass(a,"right"),this._removeClass(a,"left"),this._removeClass(a,"top")},this)),"vertical"===this.options.orientation?(this._addClass(this.sliderElem,"slider-vertical"),this.stylePos="top",this.mousePos="pageY",this.sizePos="offsetHeight"):(this._addClass(this.sliderElem,"slider-horizontal"),this.sliderElem.style.width=o,this.options.orientation="horizontal",this.options.rtl?this.stylePos="right":this.stylePos="left",this.mousePos="pageX",this.sizePos="offsetWidth"),this.options.rtl&&this._addClass(this.sliderElem,"slider-rtl"),this._setTooltipPosition(),Array.isArray(this.options.ticks)&&this.options.ticks.length>0&&(this.options.max=Math.max.apply(Math,this.options.ticks),this.options.min=Math.min.apply(Math,this.options.ticks)),Array.isArray(this.options.value)?(this.options.range=!0,this._state.value=this.options.value):this.options.range?this._state.value=[this.options.value,this.options.max]:this._state.value=this.options.value,this.trackLow=k||this.trackLow,this.trackSelection=j||this.trackSelection,this.trackHigh=l||this.trackHigh,"none"===this.options.selection?(this._addClass(this.trackLow,"hide"),this._addClass(this.trackSelection,"hide"),this._addClass(this.trackHigh,"hide")):("after"===this.options.selection||"before"===this.options.selection)&&(this._removeClass(this.trackLow,"hide"),this._removeClass(this.trackSelection,"hide"),this._removeClass(this.trackHigh,"hide")),this.handle1=m||this.handle1,this.handle2=n||this.handle2,p===!0)for(this._removeClass(this.handle1,"round triangle"),this._removeClass(this.handle2,"round triangle hide"),f=0;f<this.ticks.length;f++)this._removeClass(this.ticks[f],"round triangle hide");var I=["round","triangle","custom"],J=-1!==I.indexOf(this.options.handle);if(J)for(this._addClass(this.handle1,this.options.handle),this._addClass(this.handle2,this.options.handle),f=0;f<this.ticks.length;f++)this._addClass(this.ticks[f],this.options.handle);if(this._state.offset=this._offset(this.sliderElem),this._state.size=this.sliderElem[this.sizePos],this.setValue(this._state.value),this.handle1Keydown=this._keydown.bind(this,0),this.handle1.addEventListener("keydown",this.handle1Keydown,!1),this.handle2Keydown=this._keydown.bind(this,1),this.handle2.addEventListener("keydown",this.handle2Keydown,!1),this.mousedown=this._mousedown.bind(this),this.touchstart=this._touchstart.bind(this),this.touchmove=this._touchmove.bind(this),this.touchCapable){var K=!1;try{var L=Object.defineProperty({},"passive",{get:function(){K=!0}});window.addEventListener("test",null,L)}catch(M){}var N=K?{passive:!0}:!1;this.sliderElem.addEventListener("touchstart",this.touchstart,N),this.sliderElem.addEventListener("touchmove",this.touchmove,N)}if(this.sliderElem.addEventListener("mousedown",this.mousedown,!1),this.resize=this._resize.bind(this),window.addEventListener("resize",this.resize,!1),"hide"===this.options.tooltip)this._addClass(this.tooltip,"hide"),this._addClass(this.tooltip_min,"hide"),this._addClass(this.tooltip_max,"hide");else if("always"===this.options.tooltip)this._showTooltip(),this._alwaysShowTooltip=!0;else{if(this.showTooltip=this._showTooltip.bind(this),this.hideTooltip=this._hideTooltip.bind(this),this.options.ticks_tooltip){var O=this._addTickListener(),P=O.addMouseEnter(this,this.handle1),Q=O.addMouseLeave(this,this.handle1);this.handleCallbackMap.handle1={mouseEnter:P,mouseLeave:Q},P=O.addMouseEnter(this,this.handle2),Q=O.addMouseLeave(this,this.handle2),this.handleCallbackMap.handle2={mouseEnter:P,mouseLeave:Q}}else this.sliderElem.addEventListener("mouseenter",this.showTooltip,!1),this.sliderElem.addEventListener("mouseleave",this.hideTooltip,!1);this.handle1.addEventListener("focus",this.showTooltip,!1),this.handle1.addEventListener("blur",this.hideTooltip,!1),this.handle2.addEventListener("focus",this.showTooltip,!1),this.handle2.addEventListener("blur",this.hideTooltip,!1)}this.options.enabled?this.enable():this.disable()}var f={formatInvalidInputErrorMsg:function(a){return"Invalid input value '"+a+"' passed in"},callingContextNotSliderInstance:"Calling context element does not have instance of Slider bound to it. Check your code to make sure the JQuery object returned from the call to the slider() initializer is calling the method"},g={linear:{toValue:function(a){var b=a/100*(this.options.max-this.options.min),c=!0;if(this.options.ticks_positions.length>0){for(var d,e,f,g=0,h=1;h<this.options.ticks_positions.length;h++)if(a<=this.options.ticks_positions[h]){d=this.options.ticks[h-1],f=this.options.ticks_positions[h-1],e=this.options.ticks[h],g=this.options.ticks_positions[h];break}var i=(a-f)/(g-f);b=d+i*(e-d),c=!1}var j=c?this.options.min:0,k=j+Math.round(b/this.options.step)*this.options.step;return k<this.options.min?this.options.min:k>this.options.max?this.options.max:k},toPercentage:function(a){if(this.options.max===this.options.min)return 0;if(this.options.ticks_positions.length>0){for(var b,c,d,e=0,f=0;f<this.options.ticks.length;f++)if(a<=this.options.ticks[f]){b=f>0?this.options.ticks[f-1]:0,d=f>0?this.options.ticks_positions[f-1]:0,c=this.options.ticks[f],e=this.options.ticks_positions[f];break}if(f>0){var g=(a-b)/(c-b);return d+g*(e-d)}}return 100*(a-this.options.min)/(this.options.max-this.options.min)}},logarithmic:{toValue:function(a){var b=0===this.options.min?0:Math.log(this.options.min),c=Math.log(this.options.max),d=Math.exp(b+(c-b)*a/100);return Math.round(d)===this.options.max?this.options.max:(d=this.options.min+Math.round((d-this.options.min)/this.options.step)*this.options.step,d<this.options.min?this.options.min:d>this.options.max?this.options.max:d)},toPercentage:function(a){if(this.options.max===this.options.min)return 0;var b=Math.log(this.options.max),c=0===this.options.min?0:Math.log(this.options.min),d=0===a?0:Math.log(a);return 100*(d-c)/(b-c)}}};if(d=function(a,b){return e.call(this,a,b),this},d.prototype={_init:function(){},constructor:d,defaultOptions:{id:"",min:0,max:10,step:1,precision:0,orientation:"horizontal",value:5,range:!1,selection:"before",tooltip:"show",tooltip_split:!1,handle:"round",reversed:!1,rtl:"auto",enabled:!0,formatter:function(a){return Array.isArray(a)?a[0]+" : "+a[1]:a},natural_arrow_keys:!1,ticks:[],ticks_positions:[],ticks_labels:[],ticks_snap_bounds:0,ticks_tooltip:!1,scale:"linear",focus:!1,tooltip_position:null,labelledby:null,rangeHighlights:[]},getElement:function(){return this.sliderElem},getValue:function(){return this.options.range?this._state.value:this._state.value[0]},setValue:function(a,b,c){a||(a=0);var d=this.getValue();this._state.value=this._validateInputValue(a);var e=this._applyPrecision.bind(this);this.options.range?(this._state.value[0]=e(this._state.value[0]),this._state.value[1]=e(this._state.value[1]),this._state.value[0]=Math.max(this.options.min,Math.min(this.options.max,this._state.value[0])),this._state.value[1]=Math.max(this.options.min,Math.min(this.options.max,this._state.value[1]))):(this._state.value=e(this._state.value),this._state.value=[Math.max(this.options.min,Math.min(this.options.max,this._state.value))],this._addClass(this.handle2,"hide"),"after"===this.options.selection?this._state.value[1]=this.options.max:this._state.value[1]=this.options.min),this.options.max>this.options.min?this._state.percentage=[this._toPercentage(this._state.value[0]),this._toPercentage(this._state.value[1]),100*this.options.step/(this.options.max-this.options.min)]:this._state.percentage=[0,0,100],this._layout();var f=this.options.range?this._state.value:this._state.value[0];return this._setDataVal(f),b===!0&&this._trigger("slide",f),d!==f&&c===!0&&this._trigger("change",{oldValue:d,newValue:f}),this},destroy:function(){this._removeSliderEventHandlers(),this.sliderElem.parentNode.removeChild(this.sliderElem),this.element.style.display="",this._cleanUpEventCallbacksMap(),this.element.removeAttribute("data"),a&&(this._unbindJQueryEventHandlers(),this.$element.removeData("slider"))},disable:function(){return this._state.enabled=!1,this.handle1.removeAttribute("tabindex"),this.handle2.removeAttribute("tabindex"),this._addClass(this.sliderElem,"slider-disabled"),this._trigger("slideDisabled"),this},enable:function(){return this._state.enabled=!0,this.handle1.setAttribute("tabindex",0),this.handle2.setAttribute("tabindex",0),this._removeClass(this.sliderElem,"slider-disabled"),this._trigger("slideEnabled"),this},toggle:function(){return this._state.enabled?this.disable():this.enable(),this},isEnabled:function(){return this._state.enabled},on:function(a,b){return this._bindNonQueryEventHandler(a,b),this},off:function(b,c){a?(this.$element.off(b,c),this.$sliderElem.off(b,c)):this._unbindNonQueryEventHandler(b,c)},getAttribute:function(a){return a?this.options[a]:this.options},setAttribute:function(a,b){return this.options[a]=b,this},refresh:function(){return this._removeSliderEventHandlers(),e.call(this,this.element,this.options),a&&a.data(this.element,"slider",this),this},relayout:function(){return this._resize(),this._layout(),this},_removeSliderEventHandlers:function(){if(this.handle1.removeEventListener("keydown",this.handle1Keydown,!1),this.handle2.removeEventListener("keydown",this.handle2Keydown,!1),this.options.ticks_tooltip){for(var a=this.ticksContainer.getElementsByClassName("slider-tick"),b=0;b<a.length;b++)a[b].removeEventListener("mouseenter",this.ticksCallbackMap[b].mouseEnter,!1),a[b].removeEventListener("mouseleave",this.ticksCallbackMap[b].mouseLeave,!1);this.handle1.removeEventListener("mouseenter",this.handleCallbackMap.handle1.mouseEnter,!1),this.handle2.removeEventListener("mouseenter",this.handleCallbackMap.handle2.mouseEnter,!1),this.handle1.removeEventListener("mouseleave",this.handleCallbackMap.handle1.mouseLeave,!1),this.handle2.removeEventListener("mouseleave",this.handleCallbackMap.handle2.mouseLeave,!1)}this.handleCallbackMap=null,this.ticksCallbackMap=null,this.showTooltip&&(this.handle1.removeEventListener("focus",this.showTooltip,!1),this.handle2.removeEventListener("focus",this.showTooltip,!1)),this.hideTooltip&&(this.handle1.removeEventListener("blur",this.hideTooltip,!1),this.handle2.removeEventListener("blur",this.hideTooltip,!1)),this.showTooltip&&this.sliderElem.removeEventListener("mouseenter",this.showTooltip,!1),this.hideTooltip&&this.sliderElem.removeEventListener("mouseleave",this.hideTooltip,!1),this.sliderElem.removeEventListener("touchstart",this.touchstart,!1),this.sliderElem.removeEventListener("touchmove",this.touchmove,!1),this.sliderElem.removeEventListener("mousedown",this.mousedown,!1),window.removeEventListener("resize",this.resize,!1)},_bindNonQueryEventHandler:function(a,b){void 0===this.eventToCallbackMap[a]&&(this.eventToCallbackMap[a]=[]),this.eventToCallbackMap[a].push(b)},_unbindNonQueryEventHandler:function(a,b){var c=this.eventToCallbackMap[a];if(void 0!==c)for(var d=0;d<c.length;d++)if(c[d]===b){c.splice(d,1);break}},_cleanUpEventCallbacksMap:function(){for(var a=Object.keys(this.eventToCallbackMap),b=0;b<a.length;b++){var c=a[b];delete this.eventToCallbackMap[c]}},_showTooltip:function(){this.options.tooltip_split===!1?(this._addClass(this.tooltip,"in"),this.tooltip_min.style.display="none",this.tooltip_max.style.display="none"):(this._addClass(this.tooltip_min,"in"),this._addClass(this.tooltip_max,"in"),this.tooltip.style.display="none"),this._state.over=!0},_hideTooltip:function(){this._state.inDrag===!1&&this.alwaysShowTooltip!==!0&&(this._removeClass(this.tooltip,"in"),this._removeClass(this.tooltip_min,"in"),this._removeClass(this.tooltip_max,"in")),this._state.over=!1},_setToolTipOnMouseOver:function(a){function b(a,b){return b?[100-a.percentage[0],this.options.range?100-a.percentage[1]:a.percentage[1]]:[a.percentage[0],a.percentage[1]]}var c=this.options.formatter(a?a.value[0]:this._state.value[0]),d=a?b(a,this.options.reversed):b(this._state,this.options.reversed);this._setText(this.tooltipInner,c),this.tooltip.style[this.stylePos]=d[0]+"%"},_addTickListener:function(){return{addMouseEnter:function(a,b,c){var d=function(){var b=a._state,d=c>=0?c:this.attributes["aria-valuenow"].value,e=parseInt(d,10);b.value[0]=e,b.percentage[0]=a.options.ticks_positions[e],a._setToolTipOnMouseOver(b),a._showTooltip()};return b.addEventListener("mouseenter",d,!1),d},addMouseLeave:function(a,b){var c=function(){a._hideTooltip()};return b.addEventListener("mouseleave",c,!1),c}}},_layout:function(){var a;if(a=this.options.reversed?[100-this._state.percentage[0],this.options.range?100-this._state.percentage[1]:this._state.percentage[1]]:[this._state.percentage[0],this._state.percentage[1]],this.handle1.style[this.stylePos]=a[0]+"%",this.handle1.setAttribute("aria-valuenow",this._state.value[0]),isNaN(this.options.formatter(this._state.value[0]))&&this.handle1.setAttribute("aria-valuetext",this.options.formatter(this._state.value[0])),this.handle2.style[this.stylePos]=a[1]+"%",this.handle2.setAttribute("aria-valuenow",this._state.value[1]),isNaN(this.options.formatter(this._state.value[1]))&&this.handle2.setAttribute("aria-valuetext",this.options.formatter(this._state.value[1])),this.rangeHighlightElements.length>0&&Array.isArray(this.options.rangeHighlights)&&this.options.rangeHighlights.length>0)for(var b=0;b<this.options.rangeHighlights.length;b++){var c=this._toPercentage(this.options.rangeHighlights[b].start),d=this._toPercentage(this.options.rangeHighlights[b].end);if(this.options.reversed){var e=100-d;d=100-c,c=e}var f=this._createHighlightRange(c,d);f?"vertical"===this.options.orientation?(this.rangeHighlightElements[b].style.top=f.start+"%",this.rangeHighlightElements[b].style.height=f.size+"%"):(this.options.rtl?this.rangeHighlightElements[b].style.right=f.start+"%":this.rangeHighlightElements[b].style.left=f.start+"%",this.rangeHighlightElements[b].style.width=f.size+"%"):this.rangeHighlightElements[b].style.display="none"}if(Array.isArray(this.options.ticks)&&this.options.ticks.length>0){var g,h="vertical"===this.options.orientation?"height":"width";g="vertical"===this.options.orientation?"marginTop":this.options.rtl?"marginRight":"marginLeft";var i=this._state.size/(this.options.ticks.length-1);if(this.tickLabelContainer){var j=0;if(0===this.options.ticks_positions.length)"vertical"!==this.options.orientation&&(this.tickLabelContainer.style[g]=-i/2+"px"),j=this.tickLabelContainer.offsetHeight;else for(k=0;k<this.tickLabelContainer.childNodes.length;k++)this.tickLabelContainer.childNodes[k].offsetHeight>j&&(j=this.tickLabelContainer.childNodes[k].offsetHeight);"horizontal"===this.options.orientation&&(this.sliderElem.style.marginBottom=j+"px")}for(var k=0;k<this.options.ticks.length;k++){var l=this.options.ticks_positions[k]||this._toPercentage(this.options.ticks[k]);this.options.reversed&&(l=100-l),this.ticks[k].style[this.stylePos]=l+"%",this._removeClass(this.ticks[k],"in-selection"),this.options.range?l>=a[0]&&l<=a[1]&&this._addClass(this.ticks[k],"in-selection"):"after"===this.options.selection&&l>=a[0]?this._addClass(this.ticks[k],"in-selection"):"before"===this.options.selection&&l<=a[0]&&this._addClass(this.ticks[k],"in-selection"),this.tickLabels[k]&&(this.tickLabels[k].style[h]=i+"px","vertical"!==this.options.orientation&&void 0!==this.options.ticks_positions[k]?(this.tickLabels[k].style.position="absolute",this.tickLabels[k].style[this.stylePos]=l+"%",this.tickLabels[k].style[g]=-i/2+"px"):"vertical"===this.options.orientation&&(this.options.rtl?this.tickLabels[k].style.marginRight=this.sliderElem.offsetWidth+"px":this.tickLabels[k].style.marginLeft=this.sliderElem.offsetWidth+"px",this.tickLabelContainer.style[g]=this.sliderElem.offsetWidth/2*-1+"px"))}}var m;if(this.options.range){m=this.options.formatter(this._state.value),this._setText(this.tooltipInner,m),this.tooltip.style[this.stylePos]=(a[1]+a[0])/2+"%";var n=this.options.formatter(this._state.value[0]);this._setText(this.tooltipInner_min,n);var o=this.options.formatter(this._state.value[1]);this._setText(this.tooltipInner_max,o),this.tooltip_min.style[this.stylePos]=a[0]+"%",this.tooltip_max.style[this.stylePos]=a[1]+"%"}else m=this.options.formatter(this._state.value[0]),this._setText(this.tooltipInner,m),this.tooltip.style[this.stylePos]=a[0]+"%";if("vertical"===this.options.orientation)this.trackLow.style.top="0",this.trackLow.style.height=Math.min(a[0],a[1])+"%",this.trackSelection.style.top=Math.min(a[0],a[1])+"%",this.trackSelection.style.height=Math.abs(a[0]-a[1])+"%",this.trackHigh.style.bottom="0",this.trackHigh.style.height=100-Math.min(a[0],a[1])-Math.abs(a[0]-a[1])+"%";else{"right"===this.stylePos?this.trackLow.style.right="0":this.trackLow.style.left="0",this.trackLow.style.width=Math.min(a[0],a[1])+"%","right"===this.stylePos?this.trackSelection.style.right=Math.min(a[0],a[1])+"%":this.trackSelection.style.left=Math.min(a[0],a[1])+"%",this.trackSelection.style.width=Math.abs(a[0]-a[1])+"%","right"===this.stylePos?this.trackHigh.style.left="0":this.trackHigh.style.right="0",this.trackHigh.style.width=100-Math.min(a[0],a[1])-Math.abs(a[0]-a[1])+"%";var p=this.tooltip_min.getBoundingClientRect(),q=this.tooltip_max.getBoundingClientRect();"bottom"===this.options.tooltip_position?p.right>q.left?(this._removeClass(this.tooltip_max,"bottom"),this._addClass(this.tooltip_max,"top"),this.tooltip_max.style.top="",this.tooltip_max.style.bottom="22px"):(this._removeClass(this.tooltip_max,"top"),this._addClass(this.tooltip_max,"bottom"),this.tooltip_max.style.top=this.tooltip_min.style.top,this.tooltip_max.style.bottom=""):p.right>q.left?(this._removeClass(this.tooltip_max,"top"),this._addClass(this.tooltip_max,"bottom"),this.tooltip_max.style.top="18px"):(this._removeClass(this.tooltip_max,"bottom"),this._addClass(this.tooltip_max,"top"),this.tooltip_max.style.top=this.tooltip_min.style.top)}},_createHighlightRange:function(a,b){return this._isHighlightRange(a,b)?a>b?{start:b,size:a-b}:{start:a,size:b-a}:null},_isHighlightRange:function(a,b){return a>=0&&100>=a&&b>=0&&100>=b?!0:!1},_resize:function(a){this._state.offset=this._offset(this.sliderElem),this._state.size=this.sliderElem[this.sizePos],this._layout()},_removeProperty:function(a,b){a.style.removeProperty?a.style.removeProperty(b):a.style.removeAttribute(b)},_mousedown:function(a){if(!this._state.enabled)return!1;this._state.offset=this._offset(this.sliderElem),this._state.size=this.sliderElem[this.sizePos];var b=this._getPercentage(a);if(this.options.range){var c=Math.abs(this._state.percentage[0]-b),d=Math.abs(this._state.percentage[1]-b);this._state.dragged=d>c?0:1,this._adjustPercentageForRangeSliders(b)}else this._state.dragged=0;this._state.percentage[this._state.dragged]=b,this._layout(),this.touchCapable&&(document.removeEventListener("touchmove",this.mousemove,!1),document.removeEventListener("touchend",this.mouseup,!1)),this.mousemove&&document.removeEventListener("mousemove",this.mousemove,!1),this.mouseup&&document.removeEventListener("mouseup",this.mouseup,!1),this.mousemove=this._mousemove.bind(this),this.mouseup=this._mouseup.bind(this),this.touchCapable&&(document.addEventListener("touchmove",this.mousemove,!1),document.addEventListener("touchend",this.mouseup,!1)),document.addEventListener("mousemove",this.mousemove,!1),document.addEventListener("mouseup",this.mouseup,!1),this._state.inDrag=!0;var e=this._calculateValue();return this._trigger("slideStart",e),this._setDataVal(e),this.setValue(e,!1,!0),a.returnValue=!1,this.options.focus&&this._triggerFocusOnHandle(this._state.dragged),!0},_touchstart:function(a){if(void 0===a.changedTouches)return void this._mousedown(a);var b=a.changedTouches[0];this.touchX=b.pageX,this.touchY=b.pageY},_triggerFocusOnHandle:function(a){0===a&&this.handle1.focus(),1===a&&this.handle2.focus()},_keydown:function(a,b){if(!this._state.enabled)return!1;var c;switch(b.keyCode){case 37:case 40:c=-1;break;case 39:case 38:c=1}if(c){if(this.options.natural_arrow_keys){var d="vertical"===this.options.orientation&&!this.options.reversed,e="horizontal"===this.options.orientation&&this.options.reversed;(d||e)&&(c=-c)}var f=this._state.value[a]+c*this.options.step,g=f/this.options.max*100;if(this._state.keyCtrl=a,this.options.range){this._adjustPercentageForRangeSliders(g);var h=this._state.keyCtrl?this._state.value[0]:f,i=this._state.keyCtrl?f:this._state.value[1];f=[h,i]}return this._trigger("slideStart",f),this._setDataVal(f),this.setValue(f,!0,!0),this._setDataVal(f),this._trigger("slideStop",f),this._layout(),this._pauseEvent(b),delete this._state.keyCtrl,!1}},_pauseEvent:function(a){a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault(),a.cancelBubble=!0,a.returnValue=!1},_mousemove:function(a){if(!this._state.enabled)return!1;var b=this._getPercentage(a);this._adjustPercentageForRangeSliders(b),this._state.percentage[this._state.dragged]=b,this._layout();var c=this._calculateValue(!0);return this.setValue(c,!0,!0),!1},_touchmove:function(a){if(void 0!==a.changedTouches){var b=a.changedTouches[0],c=b.pageX-this.touchX,d=b.pageY-this.touchY;this._state.inDrag||("vertical"===this.options.orientation&&5>=c&&c>=-5&&(d>=15||-15>=d)?this._mousedown(a):5>=d&&d>=-5&&(c>=15||-15>=c)&&this._mousedown(a))}},_adjustPercentageForRangeSliders:function(a){if(this.options.range){var b=this._getNumDigitsAfterDecimalPlace(a);b=b?b-1:0;var c=this._applyToFixedAndParseFloat(a,b);0===this._state.dragged&&this._applyToFixedAndParseFloat(this._state.percentage[1],b)<c?(this._state.percentage[0]=this._state.percentage[1],this._state.dragged=1):1===this._state.dragged&&this._applyToFixedAndParseFloat(this._state.percentage[0],b)>c?(this._state.percentage[1]=this._state.percentage[0],this._state.dragged=0):0===this._state.keyCtrl&&this._state.value[1]/this.options.max*100<a?(this._state.percentage[0]=this._state.percentage[1],this._state.keyCtrl=1,this.handle2.focus()):1===this._state.keyCtrl&&this._state.value[0]/this.options.max*100>a&&(this._state.percentage[1]=this._state.percentage[0],this._state.keyCtrl=0,this.handle1.focus())}},_mouseup:function(){if(!this._state.enabled)return!1;this.touchCapable&&(document.removeEventListener("touchmove",this.mousemove,!1),document.removeEventListener("touchend",this.mouseup,!1)),document.removeEventListener("mousemove",this.mousemove,!1),document.removeEventListener("mouseup",this.mouseup,!1),this._state.inDrag=!1,this._state.over===!1&&this._hideTooltip();var a=this._calculateValue(!0);return this._layout(),this._setDataVal(a),this._trigger("slideStop",a),!1},_calculateValue:function(a){var b;if(this.options.range?(b=[this.options.min,this.options.max],0!==this._state.percentage[0]&&(b[0]=this._toValue(this._state.percentage[0]),b[0]=this._applyPrecision(b[0])),100!==this._state.percentage[1]&&(b[1]=this._toValue(this._state.percentage[1]),b[1]=this._applyPrecision(b[1]))):(b=this._toValue(this._state.percentage[0]),b=parseFloat(b),b=this._applyPrecision(b)),a){for(var c=[b,1/0],d=0;d<this.options.ticks.length;d++){var e=Math.abs(this.options.ticks[d]-b);e<=c[1]&&(c=[this.options.ticks[d],e])}if(c[1]<=this.options.ticks_snap_bounds)return c[0]}return b},_applyPrecision:function(a){var b=this.options.precision||this._getNumDigitsAfterDecimalPlace(this.options.step);return this._applyToFixedAndParseFloat(a,b)},_getNumDigitsAfterDecimalPlace:function(a){var b=(""+a).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return b?Math.max(0,(b[1]?b[1].length:0)-(b[2]?+b[2]:0)):0},_applyToFixedAndParseFloat:function(a,b){var c=a.toFixed(b);return parseFloat(c)},_getPercentage:function(a){!this.touchCapable||"touchstart"!==a.type&&"touchmove"!==a.type||(a=a.touches[0]);var b=a[this.mousePos],c=this._state.offset[this.stylePos],d=b-c;"right"===this.stylePos&&(d=-d);var e=d/this._state.size*100;return e=Math.round(e/this._state.percentage[2])*this._state.percentage[2],this.options.reversed&&(e=100-e),Math.max(0,Math.min(100,e))},_validateInputValue:function(a){if(isNaN(+a)){if(Array.isArray(a))return this._validateArray(a),a;throw new Error(f.formatInvalidInputErrorMsg(a))}return+a},_validateArray:function(a){for(var b=0;b<a.length;b++){
-var c=a[b];if("number"!=typeof c)throw new Error(f.formatInvalidInputErrorMsg(c))}},_setDataVal:function(a){this.element.setAttribute("data-value",a),this.element.setAttribute("value",a),this.element.value=a},_trigger:function(b,c){c=c||0===c?c:void 0;var d=this.eventToCallbackMap[b];if(d&&d.length)for(var e=0;e<d.length;e++){var f=d[e];f(c)}a&&this._triggerJQueryEvent(b,c)},_triggerJQueryEvent:function(a,b){var c={type:a,value:b};this.$element.trigger(c),this.$sliderElem.trigger(c)},_unbindJQueryEventHandlers:function(){this.$element.off(),this.$sliderElem.off()},_setText:function(a,b){"undefined"!=typeof a.textContent?a.textContent=b:"undefined"!=typeof a.innerText&&(a.innerText=b)},_removeClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)");d=d.replace(g," ")}a.className=d.trim()},_addClass:function(a,b){for(var c=b.split(" "),d=a.className,e=0;e<c.length;e++){var f=c[e],g=new RegExp("(?:\\s|^)"+f+"(?:\\s|$)"),h=g.test(d);h||(d+=" "+f)}a.className=d.trim()},_offsetLeft:function(a){return a.getBoundingClientRect().left},_offsetRight:function(a){return a.getBoundingClientRect().right},_offsetTop:function(a){for(var b=a.offsetTop;(a=a.offsetParent)&&!isNaN(a.offsetTop);)b+=a.offsetTop,"BODY"!==a.tagName&&(b-=a.scrollTop);return b},_offset:function(a){return{left:this._offsetLeft(a),right:this._offsetRight(a),top:this._offsetTop(a)}},_css:function(b,c,d){if(a)a.style(b,c,d);else{var e=c.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(a,b){return b.toUpperCase()});b.style[e]=d}},_toValue:function(a){return this.options.scale.toValue.apply(this,[a])},_toPercentage:function(a){return this.options.scale.toPercentage.apply(this,[a])},_setTooltipPosition:function(){var a=[this.tooltip,this.tooltip_min,this.tooltip_max];if("vertical"===this.options.orientation){var b;b=this.options.tooltip_position?this.options.tooltip_position:this.options.rtl?"left":"right";var c="left"===b?"right":"left";a.forEach(function(a){this._addClass(a,b),a.style[c]="100%"}.bind(this))}else"bottom"===this.options.tooltip_position?a.forEach(function(a){this._addClass(a,"bottom"),a.style.top="22px"}.bind(this)):a.forEach(function(a){this._addClass(a,"top"),a.style.top=-this.tooltip.outerHeight-14+"px"}.bind(this))}},a&&a.fn){var h=void 0;a.fn.slider?(windowIsDefined&&window.console.warn("bootstrap-slider.js - WARNING: $.fn.slider namespace is already bound. Use the $.fn.bootstrapSlider namespace instead."),h=c):(a.bridget(b,d),h=b),a.bridget(c,d),a(function(){a("input[data-provide=slider]")[h]()})}}(a),d});
diff --git a/examples/esp8266/WebMenu/WebMenu/data/img/icon.png b/examples/esp8266/WebMenu/WebMenu/data/img/icon.png
deleted file mode 100644
index f1f4d8e1..00000000
Binary files a/examples/esp8266/WebMenu/WebMenu/data/img/icon.png and /dev/null differ
diff --git a/examples/esp8266/WebMenu/WebMenu/data/img/logo.png b/examples/esp8266/WebMenu/WebMenu/data/img/logo.png
deleted file mode 100644
index f1f4d8e1..00000000
Binary files a/examples/esp8266/WebMenu/WebMenu/data/img/logo.png and /dev/null differ
diff --git a/examples/fieldFormat/.gitignore b/examples/fieldFormat/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/fieldFormat/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/fieldFormat/.travis.yml b/examples/fieldFormat/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/fieldFormat/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/fieldFormat/fieldFormat/fieldFormat.ino b/examples/fieldFormat/fieldFormat/fieldFormat.ino
deleted file mode 100644
index 67906449..00000000
--- a/examples/fieldFormat/fieldFormat/fieldFormat.ino
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <Arduino.h>
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-// #include <Streaming.h>
-
-using namespace Menu;
-
-int test=55;
-
-//custom field print
-//implementing a customized menu component
-//this numeric field prints formatted number with leading zeros
-template<typename T>
-class leadsField:public menuField<T> {
-public:
-  leadsField(const menuFieldShadow<T>& shadow):menuField<T>(shadow) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len) {
-    menuField<T>::reflex=menuField<T>::target();
-    prompt::printTo(root,sel,out,idx,len);
-    bool ed=this==root.navFocus;
-    out.print((root.navFocus==this&&sel)?(menuField<T>::tunning?'>':':'):' ');
-    out.setColor(valColor,sel,menuField<T>::enabled,ed);
-    char buffer[]="      ";
-    sprintf(buffer, "%03d", menuField<T>::reflex);
-    out.print(buffer);
-    out.setColor(unitColor,sel,menuField<T>::enabled,ed);
-    print_P(out,menuField<T>::units(),len);
-    return len;
-  }
-};
-
-//a menu using a customized components
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,altFIELD(leadsField,test,"Custom edit","%",0,100,10,1,doNothing,enterEvent,wrapStyle)
-  ,FIELD(test,"Original edit","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-);
-
-#define MAX_DEPTH 1
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,Serial,out);
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x testing custom fields");
-  Serial.flush();
-}
-
-void loop() {
-  nav.poll();
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/examples/fieldFormat/platformio.ini b/examples/fieldFormat/platformio.ini
deleted file mode 100644
index 2cde9488..00000000
--- a/examples/fieldFormat/platformio.ini
+++ /dev/null
@@ -1,46 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=fieldFormat
-lib_dir=~/Arduino/Libraries
-
-[env:esp12e]
-platform = espressif8266
-board = esp12e
-framework = arduino
-upload_speed=921600
-build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -lstdc++ -DDEBUG -DNOTRACE
-
-; [env:nanoatmega328]
-; platform=atmelavr
-; board=nanoatmega328
-; framework=arduino
-; upload_port=/dev/ttyUSB*
-; upload_flags=-V
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DDEBUG -DMENU_USERAM
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DDEBUG
-
-; [env:due]
-; platform = atmelsam
-; board = due
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DDEBUG
-
-; [env:esp01_1m]
-; platform = espressif8266
-; board = esp01_1m
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DDEBUG
diff --git a/examples/keypad/keypad/keypad.ino b/examples/keypad/keypad/keypad.ino
deleted file mode 100644
index f7ebf3aa..00000000
--- a/examples/keypad/keypad/keypad.ino
+++ /dev/null
@@ -1,68 +0,0 @@
-// still experimental!
-// using
-//   http://playground.arduino.cc/Code/Keypad
-//   https://github.com/Nullkraft/Keypad
-
-#include <menu.h>//menu macros and objects
-#include <menuIO/keypadIn.h>
-#include <menuIO/serialOut.h>
-
-using namespace Menu;
-
-//define your keyboard ------------------------------------
-const byte ROWS = 4; //four rows
-const byte COLS = 4; //four columns
-//define the cymbols on the buttons of the keypads
-char hexaKeys[ROWS][COLS] = {
-  {'1','2','3','A'},
-  {'4','5','6','B'},
-  {'7','8','9','-'},
-  {'/','0','*','+'},
-};
-byte rowPins[ROWS] = {6,7,8,9}; //connect to the row pinouts of the keypad
-byte colPins[COLS] = {2,3,4,5}; //connect to the column pinouts of the keypad
-
-//initialize an instance of class NewKeypad
-Keypad customKeypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
-
-//define a menu -----------------------------------------------------
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";//<-- menu will edit this text
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,SUBMENU(chooseMenu)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE
-);
-
-keypadIn kpad(customKeypad);
-NAVROOT(nav,mainMenu,MAX_DEPTH,kpad,out);
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x keypad example");
-  delay(1000);
-}
-
-void loop() {
-  nav.poll();
-  delay(100);
-}
diff --git a/examples/lolin32/include/readme.txt b/examples/lolin32/include/readme.txt
deleted file mode 100644
index 194dcd43..00000000
--- a/examples/lolin32/include/readme.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-
-This directory is intended for project header files.
-
-A header file is a file containing C declarations and macro definitions
-to be shared between several project source files. You request the use of a
-header file in your project source file (C, C++, etc) located in `src` folder
-by including it, with the C preprocessing directive `#include'.
-
-```src/main.c
-
-#include "header.h"
-
-int main (void)
-{
- ...
-}
-```
-
-Including a header file produces the same results as copying the header file
-into each source file that needs it. Such copying would be time-consuming
-and error-prone. With a header file, the related declarations appear
-in only one place. If they need to be changed, they can be changed in one
-place, and programs that include the header file will automatically use the
-new version when next recompiled. The header file eliminates the labor of
-finding and changing all the copies as well as the risk that a failure to
-find one copy will result in inconsistencies within a program.
-
-In C, the usual convention is to give header files names that end with `.h'.
-It is most portable to use only letters, digits, dashes, and underscores in
-header file names, and at most one dot.
-
-Read more about using header files in official GCC documentation:
-
-* Include Syntax
-* Include Operation
-* Once-Only Headers
-* Computed Includes
-
-https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
diff --git a/examples/lolin32/lolin32/lolin32.ino b/examples/lolin32/lolin32/lolin32.ino
deleted file mode 100644
index abb9f1f7..00000000
--- a/examples/lolin32/lolin32/lolin32.ino
+++ /dev/null
@@ -1,230 +0,0 @@
-#include <Arduino.h>
-
-/********************
-Arduino generic menu system
-lolin32 menu example
-
-output: onboard oled (i2c ssd1306 u8g2)
-input: Serial
-mcu: esp32 lolin with builtin oled
-
-*/
-
-#include <menu.h>
-#include <menuIO/u8g2Out.h>
-// #include <menuIO/encoderIn.h>
-// #include <menuIO/keyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-// #define LEDPIN LED_BUILTIN
-#define SDA 5
-#define SCL 4
-
-#include <Wire.h>
-#define fontName u8g2_font_7x13_mf
-#define fontX 7
-#define fontY 16
-#define offsetX 0
-#define offsetY 3
-#define U8_Width 128
-#define U8_Height 64
-#define USE_HWI2C
-#define fontMarginX 2
-#define fontMarginY 2
-// U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, SCL, SDA);
-U8G2_SSD1306_128X64_VCOMH0_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, SCL, SDA);//allow contrast change
-// U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, SCL, SDA);
-
-
-// define menu colors --------------------------------------------------------
-//each color is in the format:
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-// this is a monochromatic color table
-const colorDef<uint8_t> colors[] MEMMODE={
-  {{0,0},{0,1,1}},//bgColor
-  {{1,1},{1,0,0}},//fgColor
-  {{1,1},{1,0,0}},//valColor
-  {{1,1},{1,0,0}},//unitColor
-  {{0,1},{0,0,1}},//cursorColor
-  {{1,1},{1,0,0}},//titleColor
-};
-
-result doAlert(eventMask e, prompt &item);
-
-int test=55;
-
-int ledCtrl=HIGH;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) override {
-    return out.printRaw(F("special prompt!"),len);;
-  }
-};
-
-MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
-  ,OP("Sub1",doNothing,noEvent)
-  ,altOP(altPrompt,"",doNothing,noEvent)
-  ,EXIT("<Back")
-);
-
-uint16_t hrs=0;
-uint16_t mins=0;
-
-//define a pad style menu (single line menu)
-//here with a set of fields to enter a date in YYYY/MM/DD format
-altMENU(menu,timeMenu,"Time",doNothing,noEvent,noStyle,(systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
-  ,FIELD(hrs,"",":",0,11,1,0,doNothing,noEvent,noStyle)
-  ,FIELD(mins,"","",0,59,10,1,doNothing,noEvent,wrapStyle)
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={hexDigit};
-char buf1[]="0000";
-
-char* constMEM alphaNum MEMMODE=" 0123456789.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,\\|!\"#$%&/()=?~*^+-{}[]€";
-char* constMEM alphaNumMask[] MEMMODE={alphaNum};
-char name[]="          ";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",doNothing,noEvent)
-  ,OP("Op2",doNothing,noEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,EDIT("Name",name,alphaNumMask,doNothing,noEvent,noStyle)
-  ,SUBMENU(timeMenu)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Exit")
-);
-
-#define MAX_DEPTH 2
-
-serialIn serial(Serial);
-MENU_INPUTS(in,&serial);
-
-//define output device serial
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(*(Print*)&Serial,serialTops);
-
-// MENU_OUTPUTS(out,MAX_DEPTH
-//   ,U8G2_OUT(u8g2,colors,fontX,fontY,offsetX,offsetY,{0,0,U8_Width/fontX,U8_Height/fontY})
-//   ,SERIAL_OUT(Serial)
-// );//can use this macro or the following lines to define customized outputs
-
-//define output device oled
-idx_t gfx_tops[MAX_DEPTH];
-PANELS(gfxPanels,{0,0,U8_Width/fontX,U8_Height/fontY});
-u8g2Out oledOut(u8g2,colors,gfx_tops,gfxPanels,fontX,fontY,offsetX,offsetY,fontMarginX,fontMarginY);
-
-//define outputs controller
-menuOut* outputs[]{&outSerial,&oledOut};//list of output devices
-outputsList out(outputs,sizeof(outputs)/sizeof(menuOut*));//outputs list controller
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("press [select]");
-    o.setCursor(0,2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut& o,idleEvent e) {
-  o.clear();
-  switch(e) {
-    case idleStart:o.println("suspending menu!");break;
-    case idling:o.println("suspended...");break;
-    case idleEnd:o.println("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  // pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("menu 4.x test");Serial.flush();
-  Wire.begin(SDA,SCL);
-  u8g2.begin();
-  u8g2.setFont(fontName);
-  // disable second option
-  mainMenu[1].enabled=disabledStatus;
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  Serial.println("setup done.");Serial.flush();
-  u8g2.firstPage();
-  do {
-    u8g2.drawStr(0,fontY,"ArduinoMenu 4.x");
-    u8g2.drawStr(0,fontY<<1,"on lolin32");
-    u8g2.drawStr(0,fontY+(fontY<<1),"with buitin oled");
-  } while(u8g2.nextPage());
-  for(int c=255;c>0;c--) {
-    u8g2.setContrast(255-255.0*log(c)/log(255));
-    delay(8);
-  }
-  u8g2.setContrast(255);
-  delay(500);
-  nav.timeOut=60;//seconds
-}
-
-void loop() {
-  nav.doInput();
-  // digitalWrite(LEDPIN, !ledCtrl);//no led on this board
-  if (nav.changed(0)) {//only draw if menu changed for gfx device
-    u8g2.firstPage();
-    do nav.doOutput(); while(u8g2.nextPage());
-  }
-  delay(100);//simulate other tasks delay
-}
diff --git a/examples/noMacros/.gitignore b/examples/noMacros/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/noMacros/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/noMacros/.travis.yml b/examples/noMacros/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/noMacros/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/noMacros/noMacros/noMacros.ino b/examples/noMacros/noMacros/noMacros.ino
deleted file mode 100644
index 7e5ee9e4..00000000
--- a/examples/noMacros/noMacros/noMacros.ino
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <Arduino.h>
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#ifndef DEBUG
-Print& operator<<(Print&o, Menu::prompt&p) {
-  print_P(o,p.getText());
-  return o;
-}
-#endif
-
-//define "Op 1"
-void op1Func();
-constMEM char op1Text[] MEMMODE="Op 1";
-constMEM promptShadowRaw op1InfoRaw MEMMODE={(callback)op1Func,_noStyle,op1Text,enterEvent,noStyle};
-constMEM promptShadow& op1Info=*(promptShadow*)&op1InfoRaw;
-//or just this line on non AVR devices like teensy or esp8266 instead of the above three
-//promptShadow op1Info("Op 1",(callback)op1Func,enterEvent);
-prompt op1(op1Info);
-
-//define "Op 2"
-void op2Func();
-constMEM char op2Text[] MEMMODE="Op 2";
-constMEM promptShadowRaw op2InfoRaw MEMMODE={(callback)op2Func,_noStyle,op2Text,enterEvent,noStyle};
-constMEM promptShadow& op2Info=*(promptShadow*)&op2InfoRaw;
-//or just this line on non MEMMODE devices like teensy or esp8266 instead of the above three
-//promptShadow op2Info("Op 2",(callback)op2Func,enterEvent);
-prompt op2(op2Info);
-
-//define the menu
-prompt* constMEM menuData[] MEMMODE={&op1,&op2};
-//or just prompt* menuData[]={&op1,&op2}; on non avr devices
-constMEM char menuTitle[] MEMMODE="Main menu";
-constMEM menuNodeShadowRaw menuInfoRaw MEMMODE={
-  (callback)doNothing,
-  (systemStyles)(_menuData|_canNav),
-  menuTitle,
-  noEvent,
-  wrapStyle,
-  sizeof(menuData)/sizeof(prompt*),
-  menuData
-};
-constMEM menuNodeShadow& menuInfo=*(menuNodeShadow*)&menuInfoRaw;
-//or just this line on non AVR devices like teensy or esp8266 instead of the above three
-//menuNodeShadow menuInfo("Main menu",2,menuData,(callback)doNothing,noEvent,wrapStyle);
-menuNode mainMenu(menuInfo);
-
-#define MAX_DEPTH 1
-
-//define input device
-serialIn serial(Serial);
-
-//define output device
-idx_t serialTops[MAX_DEPTH]={0};
-serialOut outSerial(Serial,serialTops);
-
-//define outputs controller
-menuOut* constMEM outputs[] MEMMODE={&outSerial};//list of output devices
-outputsList out(outputs,1);//outputs list controller
-
-//define navigation root and aux objects
-navNode nav_cursors[MAX_DEPTH];//aux objects to control each level of navigation
-navRoot nav(mainMenu, nav_cursors, MAX_DEPTH, serial, out);
-
-//implement the menu actions
-void op1Func() {Serial.println("Op 1 executed");}
-void op2Func() {Serial.println("Op 2 executed");}
-
-#include <Streaming.h>
-
-/////////////////////////////////////////////////////////////////////////////
-// arduino sketch
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu initialized without macros.");
-}
-
-void loop() {
-  nav.poll();
-  delay(100);
-}
diff --git a/examples/noMacros/platformio.ini b/examples/noMacros/platformio.ini
deleted file mode 100644
index 39bdc0ea..00000000
--- a/examples/noMacros/platformio.ini
+++ /dev/null
@@ -1,34 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=noMacros
-lib_dir=~/Arduino/Libraries
-
-; [env:nanoatmega328]
-; platform = atmelavr
-; board = nanoatmega328
-; framework = arduino
-; upload_port=/dev/ttyUSB*
-; upload_flags=-V
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined
-
-[env:esp12e]
-platform = espressif8266
-board = esp12e
-framework = arduino
-upload_speed=921600
-build_flags = -Wno-comment -Wno-strict-aliasing -Wno-builtin-macro-redefined -DNODEBUG
diff --git a/examples/plugins/.gitignore b/examples/plugins/.gitignore
deleted file mode 100644
index 5dac9f52..00000000
--- a/examples/plugins/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.pioenvs
-.piolibdeps
-.clang_complete
-.gcc-flags.json
diff --git a/examples/plugins/.travis.yml b/examples/plugins/.travis.yml
deleted file mode 100644
index 2c4ff5c9..00000000
--- a/examples/plugins/.travis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Continuous Integration (CI) is the practice, in software
-# engineering, of merging all developer working copies with a shared mainline
-# several times a day < http://docs.platformio.org/page/ci/index.html >
-#
-# Documentation:
-#
-# * Travis CI Embedded Builds with PlatformIO
-#   < https://docs.travis-ci.com/user/integration/platformio/ >
-#
-# * PlatformIO integration with Travis CI
-#   < http://docs.platformio.org/page/ci/travis.html >
-#
-# * User Guide for `platformio ci` command
-#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
-#
-#
-# Please choice one of the following templates (proposed below) and uncomment
-# it (remove "# " before each line) or use own configuration according to the
-# Travis CI documentation (see above).
-#
-
-
-#
-# Template #1: General project. Test it using existing `platformio.ini`.
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio run
-
-
-#
-# Template #2: The project is intended to by used as a library with examples
-#
-
-# language: python
-# python:
-#     - "2.7"
-#
-# sudo: false
-# cache:
-#     directories:
-#         - "~/.platformio"
-#
-# env:
-#     - PLATFORMIO_CI_SRC=path/to/test/file.c
-#     - PLATFORMIO_CI_SRC=examples/file.ino
-#     - PLATFORMIO_CI_SRC=path/to/test/directory
-#
-# install:
-#     - pip install -U platformio
-#
-# script:
-#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/examples/plugins/decimalslField/decimalslField.ino b/examples/plugins/decimalslField/decimalslField.ino
deleted file mode 100644
index 3218bf89..00000000
--- a/examples/plugins/decimalslField/decimalslField.ino
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- C++ -*- */
-/********************
-May 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-www.r-site.net
-unlike native objects, pluggins can be device specific, so some pluggins might
-not work on all devices.
-all sorts of plugins may be available in the future and if you customize
-a component and think it of interest of others please do pull request.
-contrubutions and contrubutors are welcome.
-
-decimalslField - To select the number of decimal places that are printed in float and double variables types. Feb 2019 ferchinas
-                 Tested on ESP32, Oled i2c display, u8g2 driver. It could work on other devices.
-***/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define MAX_DEPTH 1
-
-unsigned char cantDecimals = 1;
-float         floatVar     = 0.123456789123456789;
-double        doubletVar   = 0.123456789123456789;
-
-void updateEvent_cb(eventMask e);    
-
-//-----Custom floatField----------------
-#define DECIMALSFLIED_DEFAULT 1
-
-template<typename T>
-class decimalslField :public menuField<T> {                //https://github.com/neu-rah/ArduinoMenu/blob/master/examples/customField/customField/customField.ino
-private:
-  idx_t decimals;
-public:
-  decimalslField(constMEM menuFieldShadow<T>& shadow) :menuField<T>(shadow) { decimals = DECIMALSFLIED_DEFAULT; }
-  decimalslField(
-    T &value,
-    constText* text,
-    constText*units,
-    T low,
-    T high,
-    T step,
-    T tune,
-    action a = doNothing,
-    eventMask e = noEvent,
-    styles s = noStyle
-  ) :decimalslField(*new menuFieldShadow<T>(value, text, units, low, high, step, tune, a, e, s)) {}
-
-  Used printTo(navRoot &root, bool sel, menuOut& out, idx_t idx, idx_t len, idx_t panelNr = 0) override {// https://github.com/neu-rah/ArduinoMenu/issues/94#issuecomment-290936646
-    //menuFieldShadow<T>& s=*(menuFieldShadow<T>*)shadow;
-    menuField<T>::reflex = menuField<T>::target();
-    idx_t l = prompt::printTo(root, sel, out, idx, len);
-    bool ed = this == root.navFocus;
-    //bool sel=nav.sel==i;
-    if (l < len) {
-      out.print((root.navFocus == this&&sel) ? (menuField<T>::tunning ? '>' : ':') : ' ');
-      l++;
-      if (l < len) {
-        l += out.print(menuField<T>::reflex, decimals);//NOTE: this can exceed the limits!
-        if (l < len) {
-          l += print_P(out, fieldBase::units(), len);
-        }
-      }
-    }
-    return l;
-  }
-
-  void setDecimals(idx_t d) { decimals = d; }
-  idx_t getDecimals(void) { return(decimals); }
-};
-//-----Custom floatField----------------END
-
- 
-decimalslField <typeof(floatVar)>& floatFlied_Object = *new decimalslField<typeof(floatVar)>(floatVar, "f", "", -100.0, 100.0, 0.1, 1);
-decimalslField <typeof(doubletVar)>& doubleFlied_Object = *new decimalslField<typeof(doubletVar)>(doubletVar, "d", "", -100.0, 100.0, 0.1, 1);
-decimalslField <typeof(cantDecimals)>& DecimalsFlied_Object = *new decimalslField<typeof(cantDecimals)>(cantDecimals, "Dec", "", 0, 18, 1, 1, (Menu::callback)updateEvent_cb, updateEvent);
-
-void updateEvent_cb(eventMask e){
-  floatFlied_Object.setDecimals(cantDecimals);
-  doubleFlied_Object.setDecimals(cantDecimals);
-  Serial.println("");Serial.print("now using '");Serial.print(cantDecimals);Serial.println("' decimals.");
- }
- 
-//---Main menu  ---------------------------------
-prompt* mainData[] = {
-  &floatFlied_Object,
-  &doubleFlied_Object,
-  &DecimalsFlied_Object,
-  new Exit("<Back")
-};
-
-menuNode& mainMenu = *new menuNode("Main menu", sizeof(mainData) / sizeof(prompt*), mainData);
-
-serialIn serial(Serial);
-MENU_INPUTS(in,&serial);
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,NONE//must have 2 items at least
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
-
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  Serial.println("Menu 4.x");
-  Serial.println("Use keys + - * /");
-  Serial.println("to control the menu navigation");
-  nav.useUpdateEvent = true;
-}
-
-void loop() {
-  nav.poll();
-}
diff --git a/examples/plugins/platformio.ini b/examples/plugins/platformio.ini
deleted file mode 100644
index d0df2b34..00000000
--- a/examples/plugins/platformio.ini
+++ /dev/null
@@ -1,39 +0,0 @@
-; PlatformIO Project Configuration File
-;
-;   Build options: build flags, source filter
-;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages
-;   Advanced options: extra scripting
-;
-; Please visit documentation for the other options and examples
-; http://docs.platformio.org/page/projectconf.html
-
-[platformio]
-src_dir=plugins
-lib_dir=~/Arduino/Libraries
-
-; [env:nanoatmega328]
-; platform = atmelavr
-; board = nanoatmega328
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined
-
-; [env:disco_f051r8]
-; platform = ststm32
-; board = disco_f051r8
-; framework = mbed
-
-; this is a raw atmega328 on a breadboard
-[env:uno]
-platform=atmelavr
-board=pro8MHzatmega328
-framework=arduino
-upload_protocol = usbasp
-upload_flags = -Pusb
-build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined -DDEBUG
-
-; [env:teensy31]
-; platform = teensy
-; board = teensy31
-; framework = arduino
-; build_flags = -Wno-comment -Wno-reorder -Wno-strict-aliasing -Wno-builtin-macro-redefined
diff --git a/examples/plugins/plugins/plugins.ino b/examples/plugins/plugins/plugins.ino
deleted file mode 100644
index ca1874ea..00000000
--- a/examples/plugins/plugins/plugins.ino
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- C++ -*- */
-/********************
-May 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-www.r-site.net
-
-unlike native objects, pluggins can be device specific, so some pluggins might
-not work on all devices.
-
-all sorts of plugins may be available in the future and if you customize
-a component and think it of interest of others please do pull request.
-
-contrubutions and contrubutors are welcome.
-
-Cancelable fields - restore original value on escape (long encoder press)
-barField - numeric field edit with a graph bar
-
-***/
-
-#include <Arduino.h>
-
-#include <menu.h>
-#ifdef DEBUG
-#include <Dump.h>
-#endif
-
-//inputs
-#include <menuIO/encoderIn.h>
-#include <menuIO/softKeyIn.h>
-#include <menuIO/chainStream.h>
-#include <menuIO/serialIn.h>
-
-//outputs
-#include <menuIO/serialOut.h>
-#include <menuIO/liquidCrystalOut.h>
-
-//include plugins
-#include <plugin/cancelField.h>
-#include <plugin/barField.h>
-
-using namespace Menu;
-
-int test=55;
-
-char* name="Edit me...";
-
-#define LEDPIN 13
-
-// LCD /////////////////////////////////////////
-#define RS 8
-#define RW 3
-#define EN 9
-LiquidCrystal lcd(RS, RW, EN, 4, 5, 6, 7);
-
-// Encoder /////////////////////////////////////
-#define encA A2
-#define encB A1
-//this encoder has a button here
-#define encBtn A3
-
-encoderIn<encA,encB> encoder;//simple quad encoder driver
-encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
-
-//a keyboard with only one key as the encoder button
-keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
-softKeyIn<1> encButton(encBtn_map);//1 is the number of keys
-
-serialIn serial(Serial);
-
-//input from the encoder + encoder button + serial
-menuIn* inputsList[]={&encStream,&encButton,&serial};
-chainStream<3> in(inputsList);//3 is the number of inputs
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-//a menu using a plugin field
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,BARFIELD(test,"Bar field","%",0,100,10,1,doNothing,noEvent,wrapStyle)//numeric field with a bar
-  ,FIELD(test,"Original","%",0,100,10,1,doNothing,noEvent,wrapStyle)//normal numeric field (2 edit levels)
-  ,FIELD(test,"O. Simple","%",0,100,1,0,doNothing,noEvent,wrapStyle)//normal numeric field (1 edit level)
-  ,altFIELD(cancelField,test,"Cancelable","%",0,100,10,1,doNothing,enterEvent,wrapStyle)//cancelable field (2 edit levels)
-  ,altFIELD(cancelField,test,"C. Simple","%",0,100,1,0,doNothing,enterEvent,wrapStyle)//cancelable field (1 edit level)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,EXIT("<Exit")
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  ,LIQUIDCRYSTAL_OUT(lcd,{0,0,16,2})
-);
-
-NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);//the navigation root object
-
-void setup() {
-  pinMode(encBtn,INPUT_PULLUP);
-  //pinMode(LEDPIN,OUTPUT);
-  Serial.begin(115200);
-  while(!Serial);
-  encoder.begin();
-  lcd.begin(16,2);
-  lcd.setCursor(0, 0);
-  lcd.print("Menu 4.x LCD");
-  lcd.setCursor(0, 1);
-  lcd.print("r-site.net");
-  serial.numValueInput=false;//numeric keys in fields used as accelerators instead
-  //Serial<<"menu 4.x plugins"<<endl;Serial.flush();
-  //setting some plugins otions
-  barFieldOptions::fill="\xFF";
-  //barFieldOptions::empty="░";//if not stick with the defaults
-  cancelFieldOptions::quitOnEsc=true;
-  cancelFieldOptions::accelSendEsc=true;//normal is enter
-  #ifdef DEBUG
-  dumpPgm(Serial,(textFieldShadowRaw*)mainMenu[5].shadow,sizeof(textFieldShadowRaw));
-  #endif
-}
-
-void loop() {
-  nav.poll();
-  if (nav.sleepTask) {
-    lcd.setCursor(0,0);
-    lcd.print((millis()/1000)%60);
-  }
-  delay(100);//simulate other tasks delay
-}
diff --git a/examples/reuse/reuse/reuse.ino b/examples/reuse/reuse/reuse.ino
deleted file mode 100644
index fd585eec..00000000
--- a/examples/reuse/reuse/reuse.ino
+++ /dev/null
@@ -1,270 +0,0 @@
-/********************
-Arduino generic menu system
-
-Sept.2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-On this case: set of alarms
-- Reusing a menu to setup multiple alatms
-- Using a very specialized prompt with alarm data
-- Using custom menu print to customize title text
-
-the alarm data is stored on the menu prompts, we use an extra alarm prompt (tmp)
-to be the editing target of the alarm setup menu.
-
-We are using Serial, however serial does a lot of redraw because of custom looks
-ideally this should run on a device that can position the cursor (not simple serial)
-you can try the ANSI serial or any LCD/graphics output
-
-Also time is tracked from millis() for simplicity, it should be tracked
-from a real time device instead. However the purpose of this demo is to
-show reutilization of a menu and customization of both menus and prompts
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-//#include <menuIO/ansiSerialOut.h>
-
-using namespace Menu;
-
-// define menu colors for ANSI terminal
-//each color is in the format:
-//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
-/*const colorDef<uint8_t> colors[] MEMMODE={
-  {{BLUE,WHITE}  ,{BLUE,WHITE,WHITE}},//bgColor
-  {{BLACK,BLACK} ,{WHITE,BLUE,BLUE}},//fgColor
-  {{BLACK,BLACK} ,{YELLOW,YELLOW,RED}},//valColor
-  {{BLACK,BLACK} ,{WHITE,BLUE,YELLOW}},//unitColor
-  {{BLACK,BLACK} ,{BLACK,BLUE,RED}},//cursorColor
-  {{BLACK,BLACK}  ,{BLUE,RED,BLUE}},//titleColor
-};*/
-
-//this is the tmp shadow data (stored on flash)
-constMEM char promptShadowTitle[] MEMMODE="";
-constMEM promptShadowRaw alarmPromptShadowRaw MEMMODE={
-  (Menu::callback)doNothing,
-  _noStyle,
-  promptShadowTitle,
-  noEvent,
-  noStyle
-};
-
-//using a special prompt to print the alarm info
-class AlarmPrompt:public prompt {
-  public:
-    bool use=false;
-    enum {alarm,countDown} type=alarm;
-    int h=0,m=0,s=0;
-    long msTime;
-    long lastTime;
-    static AlarmPrompt* selectedAlarm;
-    static idx_t selectedAlarmIdx;
-
-    AlarmPrompt(constMEM promptShadow& p):prompt(p) {}
-
-    AlarmPrompt& operator=(AlarmPrompt& o) {
-      //Serial<<"operator="<<endl;
-      use=o.use;
-      type=o.type;
-      h=o.h;
-      m=o.m;
-      s=o.s;
-      msTime=o.msTime;
-    }
-    //initialize the alarm
-    void setup() {
-      //Serial<<"alarm setup"<<endl;
-      msTime=((long)h*60*60+(long)m*60+(long)s)*1000;
-      lastTime=millis();
-    }
-    //alarm tick update
-    void update();
-    Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-      if (use) {
-        switch(type) {
-          case alarm:
-            len-=out.printRaw(F("Alarm "),len);
-            len-=out.print(h);
-            len-=out.printRaw(F(":"),len);
-            len-=out.print(m);
-            len-=out.printRaw(F(":"),len);
-            len-=out.print(s);
-            break;
-          case countDown:
-            len-=out.printRaw(F("Countdown "),len);
-            long ss=msTime/1000;
-            long hh=ss/(60*60);
-            ss-=hh*60*60;
-            long mm=ss/60;
-            ss-=mm*60;
-            if (hh<10) len-=out.print("0");
-            len-=out.print(hh);
-            len-=out.printRaw(F(":"),len);
-            if (mm<10) len-=out.print("0");
-            len-=out.print(mm);
-            len-=out.printRaw(F(":"),len);
-            if (ss<10) len-=out.print("0");
-            len-=out.print(ss);
-            break;
-        }
-      } else {
-        len-=out.printRaw(F("Alarm"),len);
-        len-=out.print(idx+1);
-        len-=out.printRaw(F(" Off"),len);
-      }
-      return len;
-    }
-    result eventHandler(eventMask e,navNode& nav,idx_t i) override;
-    static result quitAlarmSetup();
-    static void setupAlarm();
-} tmp(*(promptShadow*)&alarmPromptShadowRaw);//define a tmp object to be edited
-
-//custome menu look, prints time at title
-class AlarmMenu:public menu {
-  public:
-    AlarmMenu(constMEM menuNodeShadow& shadow):menu(shadow) {}
-    Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override {
-      long ss=millis()/1000;
-      long hh=ss/(60*60);
-      ss-=hh*60*60;
-      long mm=ss/60;
-      ss-=mm*60;
-      len-=print_P(out,getText(),len);
-      len-=out.printRaw(F(" "),len);
-      if (hh<10) len-=out.print("0");
-      len-=out.print(hh);
-      len-=out.printRaw(F(":"),len);
-      if (mm<10) len-=out.print("0");
-      len-=out.print(mm);
-      len-=out.printRaw(F(":"),len);
-      if (ss<10) len-=out.print("0");
-      len-=out.print(ss);
-      //dirty=true;useless here because dirty flag is cleaned after all devices print
-    }
-    bool changed(const navNode &nav,const menuOut& out,bool sub=true) override {
-      //this does not set the dirty flag, it  would redraw all menu causing flick
-      //however printMenu checks this as a title change signal
-      return true;//always changed!
-      //return menu::changed(nav,out,sub);//disable for debug of other parts!
-    };
-};
-//the static members (this are common to all AlarmPrompt objects)
-AlarmPrompt* AlarmPrompt::selectedAlarm=NULL;
-idx_t AlarmPrompt::selectedAlarmIdx=-1;
-
-/////////////////////////////////////////////////////////////////////////
-// MENU DEFINITION
-
-// menu for setup an alarm, we will reuse this for all alarms
-TOGGLE(tmp.use,setUse,"Use: ",doNothing,noEvent,noStyle
-  ,VALUE("Yes",true,doNothing,noEvent)
-  ,VALUE("No",false,doNothing,noEvent)
-);
-
-TOGGLE(tmp.type,setType,"Type: ",doNothing,noEvent,noStyle
-  ,VALUE("Alarm",AlarmPrompt::alarm,doNothing,enterEvent)
-  ,VALUE("Countdown",AlarmPrompt::countDown,doNothing,enterEvent)
-);
-
-//we will reuse this menu to setup all alarms
-altMENU(AlarmMenu,alarmDef,"Alarm def",doNothing,noEvent,wrapStyle,(Menu::_menuData|Menu::_canNav)
-  ,SUBMENU(setUse)
-  ,SUBMENU(setType)
-  ,FIELD(tmp.h,"Hour","",0,23,1,0,doNothing,noEvent,wrapStyle)
-  ,FIELD(tmp.m,"Minutes","",0,59,5,1,doNothing,noEvent,wrapStyle)
-  ,FIELD(tmp.s,"Seconds","",0,59,5,1,doNothing,noEvent,wrapStyle)
-  ,OP("Ok",AlarmPrompt::setupAlarm,enterEvent)
-  ,OP("Cancel",AlarmPrompt::quitAlarmSetup,enterEvent)
-);
-
-void alarm1() {Serial.println("\r\nAlarm 1 reached!");}
-void alarm2() {Serial.println("\r\nAlarm 2 reached!");}
-void alarm3() {Serial.println("\r\nAlarm 3 reached!");}
-
-//menu with list of alarms
-altMENU(AlarmMenu,mainMenu,"Alarms",doNothing,noEvent,wrapStyle,(Menu::_menuData|Menu::_canNav)
-  ,altOP(AlarmPrompt,"Alarm1",alarm1,enterEvent)
-  ,altOP(AlarmPrompt,"Alarm2",alarm2,enterEvent)
-  ,altOP(AlarmPrompt,"Alarm3",alarm3,enterEvent)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial)
-  //,ANSISERIAL_OUT(Serial,colors,{1,1,20,10})//,{18,1,16,10},{36,1,16,10})
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-idleFunc backupIdleTask=nav.idleTask;
-
-result AlarmPrompt::eventHandler(eventMask e,navNode& nav,idx_t i) {
-  selectedAlarm=this;
-  selectedAlarmIdx=i;
-  tmp=*this;
-  nav.root->useMenu(alarmDef);
-  backupIdleTask=nav.root->idleTask;
-  nav.root->idleTask=(idleFunc)quitAlarmSetup;
-  //return prompt::eventHandler(e,i);//this is reserved for alarm reach
-  return proceed;
-}
-
-//when an alarm is selected
-void AlarmPrompt::setupAlarm() {
-  *selectedAlarm=tmp;
-  selectedAlarm->setup();
-  quitAlarmSetup();
-}
-
-result AlarmPrompt::quitAlarmSetup() {
-  nav.sleepTask=NULL;//do not call idleOff! it will exaust the stack
-  nav.idleTask=backupIdleTask;
-  nav.useMenu(mainMenu);
-  nav.node().sel=selectedAlarmIdx;
-  return proceed;
-}
-
-void AlarmPrompt::update() {
-  if (use) {
-    switch(type) {
-      case countDown: {
-          long ms=millis();
-          long delta=ms-lastTime;
-          lastTime=ms;
-          msTime-=delta;
-          if (msTime<=0) {
-            use=false;
-            operator()(enterEvent,nav.node(),*this);
-          }
-        }
-        dirty=true;
-        break;
-      case alarm:
-        if (millis()>=msTime) {
-          use=false;
-          operator()(enterEvent,nav.node(),*this);
-          dirty=true;
-        }
-        break;
-    }
-  }
-}
-void setup() {
-  Serial.begin(115200);
-  while(!Serial);
-  nav.showTitle=true;
-  Serial.println("Menu 4.x reuse test");
-  delay(1000);
-  out.clear();
-}
-
-void loop() {
-  for(int n=0;n<3;n++)//update the alarms idx: 0,1,2
-    ((AlarmPrompt*)&mainMenu[n])->update();
-  nav.poll();
-  delay(300);
-}
diff --git a/examples/stm32/stm32/stm32.ino b/examples/stm32/stm32/stm32.ino
deleted file mode 100644
index 60119d36..00000000
--- a/examples/stm32/stm32/stm32.ino
+++ /dev/null
@@ -1,177 +0,0 @@
-/********************
-Arduino generic menu system
-
-Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-output: Serial3
-input: Serial3
-mcu: stm32f103 (blue pill)
-*/
-
-#include <menu.h>
-#include <menuIO/serialOut.h>
-#include <menuIO/serialIn.h>
-
-using namespace Menu;
-
-#define LEDPIN PC13
-
-result showEvent(eventMask e,navNode& nav,prompt& item) {
-  Serial3.print("event: ");
-  Serial3.println(e);
-  return proceed;
-}
-
-float test=55;
-
-result action1(eventMask e) {
-  Serial3.print(e);
-  Serial3.println(" action1 executed, proceed menu");
-  Serial3.flush();
-  return proceed;
-}
-
-result action2(eventMask e, prompt &item) {
-  Serial3.print(e);
-  Serial3.print(" action2 executed, quiting menu");
-  return quit;
-}
-
-int ledCtrl=LOW;
-
-result myLedOn() {
-  ledCtrl=HIGH;
-  return proceed;
-}
-result myLedOff() {
-  ledCtrl=LOW;
-  return proceed;
-}
-
-TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
-  ,VALUE("On",HIGH,doNothing,noEvent)
-  ,VALUE("Off",LOW,doNothing,noEvent)
-);
-
-int selTest=0;
-SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
-  ,VALUE("Zero",0,doNothing,noEvent)
-  ,VALUE("One",1,doNothing,noEvent)
-  ,VALUE("Two",2,doNothing,noEvent)
-);
-
-int chooseTest=-1;
-CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
-  ,VALUE("First",1,doNothing,noEvent)
-  ,VALUE("Second",2,doNothing,noEvent)
-  ,VALUE("Third",3,doNothing,noEvent)
-  ,VALUE("Last",-1,doNothing,noEvent)
-);
-
-//customizing a prompt look!
-//by extending the prompt class
-class altPrompt:public prompt {
-public:
-  altPrompt(constMEM promptShadow& p):prompt(p) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
-    return out.printRaw(F("special prompt!"),len);
-  }
-};
-
-MENU(subMenu,"Sub-Menu",showEvent,anyEvent,noStyle
-  ,OP("Sub1",showEvent,anyEvent)
-  ,OP("Sub2",showEvent,anyEvent)
-  ,OP("Sub3",showEvent,anyEvent)
-  ,altOP(altPrompt,"",showEvent,anyEvent)
-  ,EXIT("<Back")
-);
-
-uint16_t year=2017;
-uint16_t month=10;
-uint16_t day=7;
-
-//define a pad style menu (single line menu)
-//here with a set of fields to enter a date in YYYY/MM/DD format
-//altMENU(menu,birthDate,"Birth",doNothing,noEvent,noStyle,(systemStyles)(_asPad|Menu::_menuData|Menu::_canNav|_parentDraw)
-PADMENU(birthDate,"Birth",doNothing,noEvent,noStyle
-  ,FIELD(year,"","/",1900,3000,20,1,doNothing,noEvent,noStyle)
-  ,FIELD(month,"","/",1,12,1,0,doNothing,noEvent,wrapStyle)
-  ,FIELD(day,"","",1,31,1,0,doNothing,noEvent,wrapStyle)
-);
-
-char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
-char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
-char buf1[]="0x11";
-
-MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
-  ,OP("Op1",action1,anyEvent)
-  ,OP("Op2",action2,enterEvent)
-  ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
-  ,SUBMENU(subMenu)
-  ,SUBMENU(setLed)
-  ,OP("LED On",myLedOn,enterEvent)
-  ,OP("LED Off",myLedOff,enterEvent)
-  ,SUBMENU(selMenu)
-  ,SUBMENU(chooseMenu)
-  ,OP("Alert test",doAlert,enterEvent)
-  ,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
-  ,SUBMENU(birthDate)
-  ,EXIT("<Back")
-);
-
-#define MAX_DEPTH 2
-
-MENU_OUTPUTS(out,MAX_DEPTH
-  ,SERIAL_OUT(Serial3)
-  ,NONE//must have 2 items at least
-);
-
-serialIn serial(Serial3);
-NAVROOT(nav,mainMenu,MAX_DEPTH,serial,out);
-
-result alert(menuOut& o,idleEvent e) {
-  if (e==idling) {
-    o.setCursor(0,0);
-    o.print("alert test");
-    o.setCursor(0,1);
-    o.print("press [select]");
-    o.setCursor(0,2);
-    o.print("to continue...");
-  }
-  return proceed;
-}
-
-result doAlert(eventMask e, prompt &item) {
-  nav.idleOn(alert);
-  return proceed;
-}
-
-//when menu is suspended
-result idle(menuOut &o, idleEvent e) {
-  // o.clear();
-  switch(e) {
-    case idleStart:o.println("suspending menu!");break;
-    case idling:o.println("suspended...");break;
-    case idleEnd:o.println("resuming menu.");break;
-  }
-  return proceed;
-}
-
-void setup() {
-  pinMode(LEDPIN,OUTPUT);
-  digitalWrite(LEDPIN,!ledCtrl);
-  delay(500);
-  Serial3.begin(115200);
-  // while(!Serial);//this locks on stm32
-  Serial3.println("menu 4.x test");Serial3.flush();
-  nav.idleTask=idle;//point a function to be used when menu is suspended
-  // nav.idleOn();//this menu will start on idle state, press select to enter menu
-  //nav.doInput("323");
-  nav.timeOut=60;
-}
-
-void loop() {
-  nav.poll();
-  digitalWrite(LEDPIN, !ledCtrl);
-  delay(100);//simulate a delay when other tasks are done
-}
diff --git a/keywords.txt b/keywords.txt
deleted file mode 100644
index 51becfc7..00000000
--- a/keywords.txt
+++ /dev/null
@@ -1,96 +0,0 @@
-#####################################
-# Syntax Coloring Map For ArduinoMenu
-#####################################
-
-#####################################
-# Datatypes (KEYWORD1)
-#####################################
-
-NAVROOT	KEYWORD1
-PANELS	KEYWORD1
-MENU_INPUTS	KEYWORD1
-MENU_OUTPUTS	KEYWORD1
-OP	KEYWORD1
-MENU	KEYWORD1
-FIELD	KEYWORD1
-altOP	KEYWORD1
-altMENU	KEYWORD1
-altFIELD	KEYWORD1
-altVARIANT	KEYWORD1
-
-SUBMENU	KEYWORD1
-EXIT	KEYWORD1
-CHOOSE	KEYWORD1
-SELECT	KEYWORD1
-TOGGLE	KEYWORD1
-VALUE	KEYWORD1
-
-result	KEYWORD1
-eventMask	KEYWORD1
-systemStyles	KEYWORD1
-styles	KEYWORD1
-navCmds	KEYWORD1
-idleEvent	KEYWORD1
-
-navRoot	KEYWORD1
-navNode	KEYWORD1
-navTarget	KEYWORD1
-prompt	KEYWORD1
-menu	KEYWORD1
-menuField	KEYWORD1
-menuVariant	KEYWORD1
-menuValue	KEYWORD1
-panel	KEYWORD1
-menuOut	KEYWORD1
-toggle	KEYWORD1
-select	KEYWORD1
-choose	KEYWORD1
-
-#####################################
-# Methods and Functions (KEYWORD2)
-#####################################
-
-poll	KEYWORD2
-getCmdChar	KEYWORD2
-doNothing	KEYWORD2
-doExit	KEYWORD2
-
-#######################################
-# Constants (LITERAL1)
-#######################################
-
-proceed	LITERAL1
-quit	LITERAL1
-
-noCmd	LITERAL1
-escCmd	LITERAL1
-enterCmd	LITERAL1
-upCmd	LITERAL1
-downCmd	LITERAL1
-leftCmd	LITERAL1
-rightCmd	LITERAL1
-
-noStyle	LITERAL1
-wrapStyle	LITERAL1
-
-_noStyle	LITERAL1
-_menuData	LITERAL1
-_canNav	LITERAL1
-_parentDraw	LITERAL1
-_isVariant	LITERAL1
-
-noEvent	LITERAL1
-activateEvent	LITERAL1
-enterEvent	LITERAL1
-exitEvent	LITERAL1
-returnEvent	LITERAL1
-focusEvent	LITERAL1
-blurEvent	LITERAL1
-selFocusEvent	LITERAL1
-selBlurEvent	LITERAL1
-updateEvent	LITERAL1
-anyEvent	LITERAL1
-
-idleStart	LITERAL1
-idling	LITERAL1
-idleEnd	LITERAL1
diff --git a/library.json b/library.json
index f8bb7cb8..648b2c0d 100644
--- a/library.json
+++ b/library.json
@@ -8,6 +8,6 @@
     "url": "https://github.com/neu-rah/ArduinoMenu",
     "branch": "master"
   },
-  "frameworks": "arduino",
+  "frameworks": "*",
   "platforms": "*"
 }
diff --git a/library.properties b/library.properties
index ed04d584..162b4b16 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
 name=ArduinoMenu library
-version=4.17.19
+version=5.0.0
 author=Rui Azevedo, ruihfazevedo@gmail.com
 maintainer=neu-rah, ruihfazevedo@gmail.com
 sentence=Generic menu/interactivity system
@@ -9,4 +9,4 @@ url=https://github.com/neu-rah/ArduinoMenu
 dot_a_linkage=false
 architectures=*
 includes=menu.h
-license=CC-BY-NC-SA-4.0
+license=MIT
diff --git a/notes.md b/notes.md
new file mode 100644
index 00000000..e2892bad
--- /dev/null
+++ b/notes.md
@@ -0,0 +1,73 @@
+# AM21 notes
+
+## Output
+
+> Menu/Nav -> [Fmt] -> [Panel] -> [Measure] -> Device\<Void\>
+
+### Panel
+**Controls output device space to provide positioning/scrolling.**
+
+Devices can operate without a panel. _ex: free infinit space (Console)_
+
+Only panels that scroll on lack of free space will need a measure tool.
+This kind of panels allow multiple line heights to coexist on same menu.
+
+A `RangePanel` operates on menu items side, so they can be used on fixed line height cases.
+
+### Measure
+**Provides a method for a panel to calculates free input device area.**
+
+Even text measure can be complicated.
+- escape codes `\n \r \t ...`
+- Character surrogates
+- numeric formats
+- generic data format => API
+
+### Area
+**describes output device dimension.**
+
+
+---
+
+can data specify an output overload?
+that is an alternative output based on the current device
+
+=> output must cathegorize components hierarchy
+
+this can be used to implement pad menus
+
+1) Cathegorize output
+```c++
+enum class OutBlock {Format,Panel,Measure,Device};
+//...
+using Out=OutDef<
+  AsFormat<...>
+  AsPanel<...>
+  AsMeasure<...>
+  AsDevice<...>
+>;
+```
+
+2) Access output cathegories 
+```c++
+using OutPanel=Out::Output::Panel;
+```
+
+3) Data inclusion
+```c++
+using MainMenu=ItemDef<
+  Using<OutPanel, PadFmt >::Part,
+  StaticMenu<....>
+>;
+```
+
+4) Printing path process should pick on `Using` directives
+
+5) Compose 
+```c++
+using PadOutput<PadFmt<OutPanel>>
+```
+
+**problem** alternative composition wont provied an `obj()` that includes the output top part.
+
+**problem** overriding existing behaviors might  be a mess
\ No newline at end of file
diff --git a/parts b/parts
new file mode 160000
index 00000000..0acb5c54
--- /dev/null
+++ b/parts
@@ -0,0 +1 @@
+Subproject commit 0acb5c548c31622785f32a80fc3f583f14bd3634
diff --git a/src/baseMacros.h b/src/baseMacros.h
deleted file mode 100644
index 2dca9201..00000000
--- a/src/baseMacros.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- C++ -*- */
-//generic macros - 2014
-//Rui Azevedo (ruihfazevedo@gmail.com)
-
-#define CONCATENATE(arg1, arg2)   CONCATENATE1(arg1, arg2)
-#define CONCATENATE1(arg1, arg2)  CONCATENATE2(arg1, arg2)
-#define CONCATENATE2(arg1, arg2)  arg1##arg2
-
-#define FOR_EACH_1(what, x, ...) what(x)
-#define FOR_EACH_2(what, x, ...)\
-  what(x)\
-  FOR_EACH_1(what,  __VA_ARGS__)
-#define FOR_EACH_3(what, x, ...)\
-  what(x)\
-  FOR_EACH_2(what, __VA_ARGS__)
-#define FOR_EACH_4(what, x, ...)\
-  what(x)\
-  FOR_EACH_3(what,  __VA_ARGS__)
-#define FOR_EACH_5(what, x, ...)\
-  what(x)\
- FOR_EACH_4(what,  __VA_ARGS__)
-#define FOR_EACH_6(what, x, ...)\
-  what(x)\
-  FOR_EACH_5(what,  __VA_ARGS__)
-#define FOR_EACH_7(what, x, ...)\
-  what(x)\
-  FOR_EACH_6(what,  __VA_ARGS__)
-#define FOR_EACH_8(what, x, ...)\
-  what(x)\
-  FOR_EACH_7(what,  __VA_ARGS__)
-#define FOR_EACH_9(what, x, ...)\
-  what(x)\
-  FOR_EACH_8(what,  __VA_ARGS__)
-#define FOR_EACH_10(what, x, ...)\
-  what(x)\
-  FOR_EACH_9(what,  __VA_ARGS__)
-#define FOR_EACH_11(what, x, ...)\
-  what(x)\
-  FOR_EACH_10(what,  __VA_ARGS__)
-#define FOR_EACH_12(what, x, ...)\
-  what(x)\
-  FOR_EACH_11(what,  __VA_ARGS__)
-#define FOR_EACH_13(what, x, ...)\
-  what(x)\
-  FOR_EACH_12(what,  __VA_ARGS__)
-#define FOR_EACH_14(what, x, ...)\
-  what(x)\
-  FOR_EACH_13(what,  __VA_ARGS__)
-#define FOR_EACH_15(what, x, ...)\
-  what(x)\
-  FOR_EACH_14(what,  __VA_ARGS__)
-#define FOR_EACH_16(what, x, ...)\
-  what(x)\
-  FOR_EACH_15(what,  __VA_ARGS__)
-
-#define XFOR_EACH_1(what, params, x, ...) what(params,x)
-#define XFOR_EACH_2(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_1(what, params,  __VA_ARGS__)
-#define XFOR_EACH_3(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_2(what, params, __VA_ARGS__)
-#define XFOR_EACH_4(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_3(what, params,  __VA_ARGS__)
-#define XFOR_EACH_5(what, params, x, ...)\
-  what(params,x)\
- XFOR_EACH_4(what, params,  __VA_ARGS__)
-#define XFOR_EACH_6(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_5(what, params,  __VA_ARGS__)
-#define XFOR_EACH_7(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_6(what, params,  __VA_ARGS__)
-#define XFOR_EACH_8(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_7(what, params,  __VA_ARGS__)
-#define XFOR_EACH_9(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_8(what, params,  __VA_ARGS__)
-#define XFOR_EACH_10(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_9(what, params,  __VA_ARGS__)
-#define XFOR_EACH_11(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_10(what, params,  __VA_ARGS__)
-#define XFOR_EACH_12(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_11(what, params,  __VA_ARGS__)
-#define XFOR_EACH_13(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_12(what, params,  __VA_ARGS__)
-#define XFOR_EACH_14(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_13(what, params,  __VA_ARGS__)
-#define XFOR_EACH_15(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_14(what, params,  __VA_ARGS__)
-#define XFOR_EACH_16(what, params, x, ...)\
-  what(params,x)\
-  XFOR_EACH_15(what, params, __VA_ARGS__)
-
-#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N())
-#define FOR_EACH_NARG_(...) FOR_EACH_ARG_N(__VA_ARGS__)
-#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
-#define FOR_EACH_RSEQ_N() 16,15,14,13,12,11,10,9,8, 7, 6, 5, 4, 3, 2, 1, 0
-
-#define FOR_EACH_(N, what, x, ...) CONCATENATE(FOR_EACH_, N)(what, x, __VA_ARGS__)
-#define FOR_EACH(what, x, ...) FOR_EACH_(FOR_EACH_NARG(x, __VA_ARGS__), what, x, __VA_ARGS__)
-
-#define XFOR_EACH_(N, what, params, x, ...) CONCATENATE(XFOR_EACH_, N)(what, params, x, __VA_ARGS__)
-#define XFOR_EACH(what, params , x, ...) XFOR_EACH_(FOR_EACH_NARG(x, __VA_ARGS__), what, params, x, __VA_ARGS__)
diff --git a/src/items.cpp b/src/items.cpp
deleted file mode 100644
index c05e971b..00000000
--- a/src/items.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-#include "menuDefs.h"
-using namespace Menu;
-
-bool prompt::hasTitle(navNode& nav) const {return (nav.target->has(showTitle)||(nav.root->showTitle&&!nav.target->has(noTitle)));}
-
-idx_t prompt::printRaw(menuOut& out,idx_t len) const {
-  trace(MENU_DEBUG_OUT<<"prompt::printRaw"<<endl;print_P(MENU_DEBUG_OUT,getText(),len));
-  return print_P(out,getText(),len);
-}
-
-bool prompt::changed(const navNode &nav,const menuOut& out,bool sub,bool test) {
-  trace(MENU_DEBUG_OUT<<"prompt::changed"<<endl);
-  return dirty;
-}
-
-result prompt::eventHandler(eventMask e,navNode& nav,idx_t i) {
-  return operator()(e,nav,*this);
-}
-
-#ifdef MENU_FMT_WRAPS
-  classes prompt::type() const {return promptClass;}
-#endif
-
-Used prompt::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-  trace(MENU_DEBUG_OUT<<*(prompt*)this<<" prompt::printTo"<<endl);
-  #ifdef MENU_FMT_WRAPS
-    out.fmtStart(*this,menuOut::fmtPrompt,root.node(),idx);
-  #endif
-  idx_t r=printRaw(out,len);
-  #ifdef MENU_FMT_WRAPS
-    out.fmtEnd(*this,menuOut::fmtPrompt,root.node(),idx);
-  #endif
-  if (is((systemStyles)(_menuData|_parentDraw|_asPad))
-    //&&((&((menuNode*)root.node().target)->operator[](idx))==this)
-  ) {
-    trace(MENU_DEBUG_OUT<<*(prompt*)this<<" some parentDraw or asPad menu... idx:"<<idx<<endl);
-    // #ifdef MENU_FMT_WRAPS
-    //   out.fmtStart(*this,menuOut::fmtBody,root.node(),idx);
-    // #endif
-    if (root.node().target==this) {
-      trace(MENU_DEBUG_OUT<<"calling printMenu"<<endl);
-      out.printMenu(root.node(), panelNr);
-    } else {
-      trace(MENU_DEBUG_OUT<<"previewMenu"<<endl);
-      out.previewMenu(root,*(menuNode*)this,panelNr);
-    }
-    // #ifdef MENU_FMT_WRAPS
-    //   out.fmtEnd(*this,menuOut::fmtBody,root.node(),idx);
-    // #endif
-  }
-  return r;
-}
-
-#ifdef MENU_ASYNC
-  idx_t prompt::selected() const {return 0;}
-  const char* prompt::typeName() const {return "prompt";}
-  bool prompt::async(const char*uri,navRoot& root,idx_t lvl) {
-    _trace(MENU_DEBUG_OUT<<"prompt::async ["<<uri<<"]"<<endl;);
-    return true;
-  }
-  idx_t menuNode::parseUriNode(const char*&uri) {
-    if (*uri=='/') uri++;//TODO check who does this part!
-    bool neg=false;
-    if (*uri=='-') {
-      uri++;
-      neg=true;
-    }
-    assert(*uri=='-'||strchr(numericChars,uri[0]));
-    int n=0;
-    while (*uri) {
-      char* d=strchr(numericChars,uri[0]);
-      if (d) n=n*10+((*d)-'0');
-      else break;
-      uri++;
-    }
-    //state transformation (for events preservation)
-    if (neg) n=sz()-n;//allow negative index from end of list
-    if (n<0) n=0;
-    else if (n>=sz()) n=sz()-1;//never trusting web!
-    return n;
-  }
-
-  bool menuNode::async(const char*uri,navRoot& root,idx_t lvl) {
-    trace(MENU_DEBUG_OUT<<*(prompt*)this<<" menuNode::async "<<uri<<" lvl:"<<lvl<<" root.level:"<<root.level<<endl);
-    // assert(root.path[lvl].target==this);
-    if ((!uri[0])||(uri[0]=='/'&&!uri[1])) {
-      root.escTo(lvl);
-      trace(MENU_DEBUG_OUT<<*(prompt*)this<<" async true! "<<uri<<endl);
-      return true;
-    }
-    if (uri[0]=='/') uri++;//TODO check who does this part!
-    assert(strchr(numericChars,uri[0]));
-    int n=parseUriNode(uri);
-    trace(MENU_DEBUG_OUT<<"n:"<<n<<" sel:"<<root.path[lvl].sel<<endl);
-    _trace(Serial<<"root.level>lvl:"<<(root.level>lvl)<<endl);
-    _trace(Serial<<"root.path[lvl].sel==n:"<<(root.path[lvl].sel==n)<<endl);
-    _trace(Serial<<"root.path[lvl+1].target==&operator[](n))):"<<(root.path[lvl+1].target==&operator[](n))<<endl);
-    _trace(Serial<<"operator[](n).type()==toggleClass:"<<(operator[](n).type()==toggleClass)<<endl);
-    bool toggleUpdate=operator[](n).type()==toggleClass&&strchr(uri,'/');
-    if (!(
-        //if updating a toggle to not toggle the value, was deffault action
-        //but as we can't enter toggles this action would be preceeding every update otherwise.
-        toggleUpdate
-        ||(root.level>lvl&&root.path[lvl].sel==n&&root.path[lvl+1].target==&operator[](n))
-      )) {
-      _trace(Serial<<"menuNode, escTo "<<lvl<<endl);
-      root.escTo(lvl/*+(lvl&&root.path[lvl].sel==n?-1:0)*/);
-      _trace(Serial<<"menuNode, doNav "<<n<<endl);
-      root.doNav(navCmd(idxCmd,n));
-    }
-    _trace(Serial<<"menuNode, proceed async"<<endl);
-    operator[](n).async(uri,root,lvl+1);
-    if (toggleUpdate)
-      root.node().event(root.useUpdateEvent?updateEvent:enterEvent,n);
-    return true;
-  }
-  const char* navTarget::typeName() const {return "navTarget";}
-#endif
-
-constText* textField::validator(int i) {return ((textFieldShadow*)shadow)->operator[](i%sz());}
-
-#ifdef MENU_FMT_WRAPS
-  classes textField::type() const {return textFieldClass;}
-#endif
-
-#ifdef MENU_ASYNC
-  const char* textField::typeName() const {return "textField";}
-#endif
-
-
-void textField::doNav(navNode& nav,navCmd cmd) {
-  trace(MENU_DEBUG_OUT<<"textField::doNav:"<<cmd.cmd<<endl);
-  switch(cmd.cmd) {
-    case enterCmd:
-      if (edited&&!charEdit) {
-        edited=false;
-        cursor=0;
-        nav.root->exit();
-      } else {
-        charEdit=!charEdit;
-        dirty=true;
-        edited=true;
-      }
-      break;
-    case escCmd:
-      dirty=true;
-      if (charEdit) charEdit=false;
-      else {
-        edited=false;
-        cursor=0;
-        nav.root->exit();
-      }
-      break;
-    case upCmd:
-      if (charEdit) {
-        const char* v=validator(cursor);
-        char *at=strchr(v,buffer()[cursor]);
-        idx_t pos=at?at-v+1:1;
-        if (pos>=(idx_t)strlen(v)) pos=0;
-        buffer()[cursor]=v[pos];
-        dirty=true;
-      } else {
-        if(cursor<(idx_t)strlen(buffer())-1) cursor++;
-        // if(cursor<sz()) cursor++;
-        edited=false;
-      }
-      dirty=true;
-      break;
-    case downCmd:
-      if (charEdit) {
-        const char* v=validator(cursor);
-        char *at=strchr(v,buffer()[cursor]);//at is not stored on the class to save memory
-        idx_t pos=at?at-v-1:0;
-        if (pos<0) pos=strlen(v)-1;
-        buffer()[cursor]=v[pos];
-        dirty=true;
-      } else {
-        if (cursor) cursor--;
-        edited=false;
-      }
-      dirty=true;
-      break;
-    default:break;
-  }
-  trace(MENU_DEBUG_OUT<<"cursor:"<<cursor<<endl);
-}
-
-Used textField::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-  trace(MENU_DEBUG_OUT<<*this<<" textField::printTo"<<endl);
-  // out.fmtStart(menuOut::fmtPrompt,root.node(),idx);
-  bool editing=this==root.navFocus;
-  trace(MENU_DEBUG_OUT<<"editing:"<<editing<<" len:"<<len;)
-  idx_t l=navTarget::printTo(root,sel,out,idx,len,panelNr);
-  #ifdef MENU_FMT_WRAPS
-    out.fmtStart(*this,menuOut::fmtEditCursor,root.node(),idx);
-  #endif
-  if (l<len) {
-    out.write(editing?":":" ");
-    l++;
-  }
-  #ifdef MENU_FMT_WRAPS
-    out.fmtEnd(*this,menuOut::fmtEditCursor,root.node(),idx);
-  #endif
-  // idx_t c=l;
-  //idx_t top=out.tops[root.level];
-  #ifdef MENU_FMT_WRAPS
-    out.fmtStart(*this,menuOut::fmtTextField,root.node(),idx);
-  #endif
-  idx_t tit=hasTitle(root.node())?1:0;
-  idx_t line=idx+tit;//-out.tops[root.level];
-  idx_t c=l+1;
-  idx_t w=len-l;
-  idx_t at=cursor>=w?cursor-w:0;
-  trace(MENU_DEBUG_OUT<<"at:"<<at<<" tit:"<<tit<<" line:"<<line<<" cursor:"<<cursor<<" l:"<<l<<" len:"<<len);//<<endl;)
-  while(buffer()[at]&&l++<len)
-    if (at==cursor&&editing) {
-      // MENU_DEBUG_OUT<<"idx:"<<idx<<" line:"<<line<<" at:"<<at<<" l:"<<l<<endl;
-      // c=l+1;
-      l+=out.startCursor(root,l,line,charEdit);//draw text cursor or color code start
-      out.write(buffer()[at++]);//draw focused character
-      l+=out.endCursor(root,l,line,charEdit);//draw text cursor or color code end
-    } else out.write(buffer()[at++]);
-  out.editCursor(root,c+cursor,line,editing,charEdit);//reposition a gfx cursor
-  #ifdef MENU_FMT_WRAPS
-    out.fmtEnd(*this,menuOut::fmtTextField,root.node(),idx);
-  #endif
-  return l;
-}
-
-#ifdef MENU_FMT_WRAPS
-  classes fieldBase::type() const {return fieldClass;}
-#endif
-
-#ifdef MENU_ASYNC
-  const char* fieldBase::typeName() const {return "fieldBase";}
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-// menuNode - any menu object that has a list of members
-//
-////////////////////////////////////////////////////////////////////////////////
-bool menuNode::changed(const navNode &nav,const menuOut& out,bool sub,bool test) {
-  trace(MENU_DEBUG_OUT<<*this<<" menuNode::changed"<<endl);
-  return menuNode::_changes<false>(nav,out,sub,test);
-}
-
-void menuNode::clearChanged(const navNode &nav,const menuOut& out,bool sub) {
-  trace(MENU_DEBUG_OUT<<" menuOut::clearChanged "<<nav);
-  _changes<true>(nav,out,sub,false);
-}
-
-#ifdef MENU_FMT_WRAPS
-  classes menuNode::type() const {return menuClass;}
-#endif
-
-#ifdef MENU_ASYNC
-  const char* menuNode::typeName() const {return "mn";}
-#endif
-
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-// navTarget - any menu object that can process keys/input
-//
-////////////////////////////////////////////////////////////////////////////////
-
-void navTarget::doNav(navNode& nav,navCmd cmd) {
-  trace(MENU_DEBUG_OUT<<"navTarget::doNav"<<endl);
-  nav.doNavigation(cmd);
-}
-
-void navTarget::parseInput(navNode& nav,menuIn& in) {
-  trace(MENU_DEBUG_OUT<<"navTarget::parseInput"<<endl);
-  doNav(nav,nav.navKeys(in.read()));
-}
-
-void textField::parseInput(navNode& nav,menuIn& in) {
-  trace(MENU_DEBUG_OUT<<"navTarget::parseInput"<<endl);
-  if (/*charEdit&&*/in.available()) {
-    char c=in.peek();
-    if (options->useNavChars&&(c==options->getCmdChar(upCmd)
-      ||c==options->getCmdChar(downCmd)
-      ||c==options->getCmdChar(enterCmd)
-      ||c==options->getCmdChar(escCmd))) {
-        navTarget::parseInput(nav,in);
-        return;
-      }
-    switch(c) {//special cases
-      case 0x0D://enter
-        in.read();
-        charEdit=false;
-        dirty=true;
-        // edited=false;
-        cursor=0;
-        nav.root->exit();
-        return;
-      case 0x08://backspace
-        in.read();
-        buffer()[cursor]=validator(cursor)[0];
-        if (cursor) cursor--;
-        dirty=true;
-        return;
-      default: {
-        const char* v=validator(cursor);
-        char *at=strchr(v,c);
-        if (at) {
-          in.read();
-          buffer()[cursor]=c;
-          if (cursor<(idx_t)strlen(buffer())-1) cursor++;
-          dirty=true;
-          return;
-        }
-        // MENU_DEBUG_OUT<<hex(c)<<endl;
-        navTarget::parseInput(nav,in);
-      }
-    }
-  }
-}
-
-#ifdef MENU_ASYNC
-bool textField::async(const char*uri,navRoot& root,idx_t lvl=0) {
-  trace(MENU_DEBUG_OUT<<"textField::async "<<uri<<endl);
-  if ((!*uri)||(uri[0]=='/'&&!uri[1])) return true;
-  if (uri[0]=='/') {
-    StringStream i(++uri);
-    memset(buffer(), validator(0)[0], (idx_t)strlen(buffer()));//clear buffer
-    while(i.available()) parseInput(root.node(), i);
-    trace(MENU_DEBUG_OUT<<"textField::enterCmd"<<endl);
-    doNav(root.node(),escCmd);
-    return true;
-  }
-  return true;
-}
-
-bool fieldBase::async(const char *uri,navRoot& root,idx_t lvl) {
-  trace(MENU_DEBUG_OUT<<"fieldBase::async "<<uri<<endl);
-  if ((!*uri)||(uri[0]=='/'&&!uri[1])) return true;
-  else if (uri[0]=='/') {
-    StringStream i(++uri);
-    parseInput(root.node(), i);
-    return true;
-  }
-  return true;
-}
-#endif
-
-void fieldBase::doNav(navNode& nav,navCmd cmd) {
-  trace(MENU_DEBUG_OUT<<"fieldBase::doNav "<<cmd;MENU_DEBUG_OUT<<endl);
-  switch(cmd.cmd) {
-    //by default esc and enter cmds do the same by changing the value
-    //it might be set by numeric parsing when allowed
-    case idxCmd: //MENU_DEBUG_OUT<<"menuField::doNav with idxCmd"<<endl;
-    case escCmd:
-      tunning=true;//prepare for exit
-    case enterCmd:
-      if (tunning||nav.root->nav2D||!canTune()) {//then exit edition
-        tunning=false;
-        dirty=true;
-        constrainField();
-        nav.event(nav.root->useUpdateEvent?updateEvent:enterEvent);
-        nav.root->exit();
-        return;
-      } else tunning=true;
-      dirty=true;
-      break;
-    case upCmd:
-      stepit(1);
-      break;
-    case downCmd:
-      stepit(-1);
-      break;
-    default:break;
-  }
-  if (dirty)//sending enter or update event
-    nav.event(nav.root->useUpdateEvent?updateEvent:enterEvent);
-}
-
-Used fieldBase::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-  trace(MENU_DEBUG_OUT<<"fieldBase::printTo"<<endl);
-  idx_t l=prompt::printTo(root,sel,out,idx,len,panelNr);
-  bool ed=this==root.navFocus;
-  //bool sel=nav.sel==i;
-  if (l<len) {
-    //TODO: remove cursor when printing asPad menus
-    // if(!root.node().has(_asPad))//do notdraw edit cursors for pad menu items?
-    //this is not really working!
-    out.print((root.navFocus==this&&sel)?(tunning?'>':':'):' ');
-    l++;
-    if (l<len) {
-      #ifdef MENU_FMT_WRAPS
-        out.fmtStart(*this,menuOut::fmtField,root.node(),idx);
-      #endif
-      out.setColor(valColor,sel,enabled,ed);
-      //out<<reflex;
-      l+=printReflex(out);//NOTE: this can exceed the limits!
-      #ifdef MENU_FMT_WRAPS
-        out.fmtEnd(*this,menuOut::fmtField,root.node(),idx);
-      #endif
-      if (l<len) {
-        #ifdef MENU_FMT_WRAPS
-          out.fmtStart(*this,menuOut::fmtUnit,root.node(),idx);
-        #endif
-        out.setColor(unitColor,sel,enabled,ed);
-        l+=print_P(out,units(),len);
-        #ifdef MENU_FMT_WRAPS
-          out.fmtEnd(*this,menuOut::fmtUnit,root.node(),idx);
-        #endif
-      }
-    }
-  }
-  return l;
-}
-
-/////////////////////////////////////////////////////////////////
-Used menuVariantBase::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-  trace(MENU_DEBUG_OUT<<"menuVariantBase::printTo"<<endl);
-  idx_t l=len;
-  l-=prompt::printTo(root,sel,out,idx,len,panelNr);
-  idx_t at=sync(sync());
-  bool ed=this==root.navFocus;
-  //bool sel=nav.sel==i;
-  if (len-l<0) return 0;
-  out.print(this==&root.active()?':':' ');
-  l--;
-  #ifdef MENU_FMT_WRAPS
-    if (out.fmtStart(*this,type()==selectClass?menuOut::fmtSelect:menuOut::fmtChoose,root.node(),idx)==proceed) {
-  #endif
-    // MENU_DEBUG_OUT<<"variant ";
-    // print_P(MENU_DEBUG_OUT,operator[](at).getText());
-    // MENU_DEBUG_OUT<<endl;
-    out.setColor(valColor,sel,prompt::enabled,ed);
-    if (l>0) l-=operator[](at).printRaw(out,l);
-  #ifdef MENU_FMT_WRAPS
-    }
-  #endif
-  #ifdef MENU_FMT_WRAPS
-  out.fmtEnd(*this,type()==selectClass?menuOut::fmtSelect:menuOut::fmtChoose,root.node(),idx);
-  #endif
-  trace(MENU_DEBUG_OUT<<"menuVariantBase::printTo ended!"<<endl);
-  return len-l;
-}
-
-idx_t menuVariantBase::togglePrintTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-  trace(MENU_DEBUG_OUT<<"menuVariantBase::togglePrintTo"<<endl);
-  idx_t l=prompt::printTo(root,sel,out,idx,len,panelNr);
-  idx_t at=sync(sync());
-  bool ed=this==root.navFocus;
-  //bool sel=nav.sel==i;
-  out.setColor(valColor,sel,prompt::enabled,ed);
-  //out<<menuNode::operator[](at);
-  if (len-l>0) {
-    #ifdef MENU_FMT_WRAPS
-  out.fmtStart(*this,menuOut::fmtToggle,root.node(),idx);
-    #endif
-    l+=operator[](at).printRaw(out,len-l);
-    #ifdef MENU_FMT_WRAPS
-  out.fmtEnd(*this,menuOut::fmtToggle,root.node(),idx);
-    #endif-
-  }
-  return l;
-}
-
-void menuVariantBase::doNav(navNode& nav,navCmd cmd) {
-  trace(MENU_DEBUG_OUT<<"menuVariantBase::doNav"<<endl);
-  nav.sel=sync();
-  navCmd c=nav.doNavigation(cmd);
-  sync(nav.sel);
-  if (c.cmd==enterCmd) {
-    nav.root->exit();
-  }
-}
-
-template<bool clear>
-bool menuNode::_changes(const navNode &nav,const menuOut& out,bool sub,bool test) {
-  if (clear) dirty=false;
-  else if (dirty) {
-    trace(if (test) MENU_DEBUG_OUT<<"just dirty!"<<endl);
-    return true;
-  }
-  if (has((systemStyles)(_asPad|_parentDraw))) {
-    trace(MENU_DEBUG_OUT<<*this<<" sz:"<<sz()<<" asPad or parentDraw"<<endl);
-    for(int i=0;i<sz();i++)
-      if (clear) operator[](i).clearChanged(nav,out,false);
-      else if (operator[](i).changed(nav,out,false,test)) {
-        trace(if (test) MENU_DEBUG_OUT<<"APPD! "<<operator[](i)<<endl);
-        return true;
-      }
-    return false;
-  } else {
-    if (!(clear||(nav.target==this&&sub))) {
-      trace(if (test&&dirty) MENU_DEBUG_OUT<<"indirect!"<<endl);
-      return dirty;// second hand check, just report self
-    }
-    idx_t level=nav.root->level;
-    if (parentDraw()) {
-      if (clear) nav.root->path[level-1].target->clearChanged(nav.root->path[level-1],out,sub);
-      else {
-        trace(MENU_DEBUG_OUT<<"return changed of parent-draw element"<<endl);
-        trace(if (test) MENU_DEBUG_OUT<<"parentDraw()!"<<endl);
-        return nav.root->path[level-1].target->changed(nav.root->path[level-1],out,sub,test);
-      }
-    }
-    idx_t my=out.maxY()-((has(showTitle)||(nav.root->showTitle&&!has(noTitle)))?1:0);
-    menuNode* target=nav.root->path[level].target;
-    idx_t t=out.tops[level-(target->has(_asPad)||target->has(_parentDraw))];
-    trace(MENU_DEBUG_OUT<<"t:"<<t<<endl;);
-    if (sub) for(int i=0;i<my;i++,t++) {
-      if (t>=sz()) break;
-      if (clear) operator[](t).clearChanged(nav,out,false);
-      {
-        trace(MENU_DEBUG_OUT<<"checking:"<<operator[](t)<<endl);
-        if (operator[](t).changed(nav,out,false,test)) {
-          trace(if (test) MENU_DEBUG_OUT<<"sub changed!"<<endl);
-          return true;
-        }
-      }
-    }
-  }
-  if (clear) {
-    #ifdef MENU_DEBUG
-      if(changed(nav,out,sub,true)) {
-        MENU_DEBUG_OUT<<"\nERROR clear changed fail!"<<endl;
-        MENU_DEBUG_OUT<<*this<<endl;
-        MENU_DEBUG_OUT<<"level:"<<nav.root->level<<endl;
-        // MENU_DEBUG_OUT<<"type:"<<type()<<endl;
-        MENU_DEBUG_OUT.flush();
-        // while(1);
-        return false;
-      }
-    #endif
-    return true;
-  } else return false;
-}
-
-#ifdef MENU_ASYNC
-  const char* menu::typeName() const {return "menu";}
-#endif
-
-#ifdef MENU_ASYNC
-  const char* menuVariantBase::typeName() const {return "menuVariantBase";}
-#endif
diff --git a/src/items.h b/src/items.h
deleted file mode 100644
index a08617bd..00000000
--- a/src/items.h
+++ /dev/null
@@ -1,387 +0,0 @@
-/* -*- C++ -*- */
-#ifndef RSITE_ARDUINO_MENU_SYSTEM_ITEMS
-  #define RSITE_ARDUINO_MENU_SYSTEM_ITEMS
-
-  #include "menuBase.h"
-  #include "shadows.h"
-
-  namespace Menu {
-
-    #ifdef MENU_FMT_WRAPS
-      enum classes {noClass=0,promptClass,textFieldClass,fieldClass,toggleClass,selectClass,chooseClass,valueClass,menuClass};
-    #endif
-
-    #ifdef MENU_ASYNC
-      template<typename T> inline const char* typeStr() {return "o";}
-      template<> inline const char* typeStr<uint8_t>() {return "u8";}
-      template<> inline const char* typeStr<uint16_t>() {return "u16";}
-      template<> inline const char* typeStr<uint32_t>() {return "u32";}
-      template<> inline const char* typeStr<int8_t>() {return "i8";}
-      template<> inline const char* typeStr<int16_t>() {return "i16";}
-      template<> inline const char* typeStr<int32_t>() {return "i32";}
-      // template<> inline const char* typeStr<long>() {return "long";}
-      // template<> inline const char* typeStr<unsigned long>() {return "unsigned long";}
-      // template<> inline const char* typeStr<long long>() {return "long long";}
-      // template<> inline const char* typeStr<unsigned long long>() {return "unsigned long long";}
-      template<> inline const char* typeStr<float>() {return "f";}
-      template<> inline const char* typeStr<double>() {return "d";}
-    #endif
-    // Menu objects and data
-    //////////////////////////////////////////////////////////////////////////
-    class prompt {
-      friend class navNode;
-      friend class menuOut;
-      protected:
-      public:
-        constMEM promptShadow* shadow;//constant read-only data (PROGMEM)
-      public:
-        status enabled=enabledStatus;//ignore enter if false
-        bool dirty=true;//needs to be  redrawn
-        inline uint16_t hash() const {
-          int tmp=(int)this;
-          return ((uint16_t*)&tmp)[sizeof(this)/sizeof(uint16_t)-1];
-        }
-        inline prompt(constMEM promptShadow& shadow):shadow(&shadow) {}
-        inline prompt(constText* t,action a=doNothing,eventMask e=noEvent,styles s=noStyle,systemStyles ss=_noStyle)
-          :shadow(new promptShadow(t,a,e,s,ss)) {}
-        inline void enable() {enabled=enabledStatus;}
-        inline void disable() {enabled=disabledStatus;}
-        inline constText* getText() const {return shadow->getText();}
-
-        inline systemStyles sysStyles() const {return shadow->_sysStyles();}
-        inline styles style() const {return shadow->_style();}
-        inline eventMask events() const {return shadow->_events();}
-
-        inline bool is(systemStyles chk)  const {return (sysStyles()&chk)==chk;}
-        inline bool has(systemStyles chk) const {return sysStyles()&chk;}
-        inline bool is(styles chk)        const {return (style()&chk)==chk;}
-        inline bool has(styles chk)       const {return style()&chk;}
-        inline bool is(eventMask chk)     const {return (events()&chk)==chk;}
-        inline bool has(eventMask chk)    const {return events()&chk;}
-
-        inline bool canWrap()    const {return style()&wrapStyle;}
-        inline bool canNav()     const {return sysStyles()&_canNav;}//can receive navigation focus and process keys
-        inline bool isMenu()     const {return sysStyles()&_menuData;}//has menu data list and can be a navNode target
-        inline bool isVariant()  const {return sysStyles()&_isVariant;}//a menu as an enumerated field, connected to a variable value
-        inline bool parentDraw() const {return sysStyles()&_parentDraw;}//a menu as an enumerated field, connected to a variable value
-        inline bool asPad()      const {return sysStyles()&_asPad;}//a menu as an enumerated field, connected to a variable value
-
-        inline bool hasTitle(navNode& nav) const;
-
-        inline result operator()(FUNC_PARAMS) const {return (*shadow)(FUNC_VALUES);}
-        idx_t printRaw(menuOut& out,idx_t len) const;
-
-        virtual void clearChanged(const navNode &nav,const menuOut& out,bool sub) {dirty=false;}
-        virtual Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0);//raw print to output device
-        virtual bool changed(const navNode &nav,const menuOut& out,bool sub=true,bool test=false);
-        //this is the system version of enter handler, its used by elements like toggle
-        virtual result sysHandler(SYS_FUNC_PARAMS) {return proceed;}
-        virtual result eventHandler(eventMask e,navNode& nav,idx_t i);
-        #ifdef MENU_FMT_WRAPS
-          virtual classes type() const;
-        #endif
-        #ifdef MENU_ASYNC
-          // virtual prompt* seek(idx_t* uri,idx_t len) {return len?NULL:this;}
-          virtual bool async(const char*uri,navRoot& root,idx_t lvl);
-          //some functions to use on htmlFmt
-          // for enumerations:
-          virtual idx_t selected() const;
-          virtual const char* typeName() const;
-        #endif
-        #ifdef MENU_ASYNC
-          virtual void printValue(menuOut&) const {}
-          virtual void printHigh(menuOut&) const {}
-          virtual void printLow(menuOut&) const {}
-          virtual void printStep(menuOut& o) const {};
-          virtual void printTune(menuOut& o) const {};
-        #endif
-    };
-
-    class Exit:public prompt {
-      public:
-        inline Exit(constText* t):prompt(t,(callback)doExit,enterEvent) {}
-    };
-
-    //--------------------------------------------------------------------------
-    // can receive navigation focus and process keys
-    // this is the minimal candidate for navRoot::navFocus
-    class navTarget:public prompt {
-      public:
-        inline navTarget(constMEM promptShadow& shadow):prompt(shadow) {}
-        inline navTarget(constText* t,action a=doNothing,eventMask e=noEvent,styles s=noStyle,systemStyles ss=_noStyle)
-          :prompt(t,a,e,s,ss) {}
-        virtual void parseInput(navNode& nav,menuIn& in);
-        virtual void doNav(navNode& nav,navCmd cmd);
-        #ifdef MENU_ASYNC
-          const char* typeName() const override;
-        #endif
-    };
-
-    //--------------------------------------------------------------------------
-    class textField:public navTarget {
-    public:
-      // int hash=0;//not implemented yet
-      bool charEdit=false;
-      bool edited=false;
-      idx_t cursor=0;
-      inline textField(constMEM textFieldShadow& shadow):navTarget(shadow) {}
-      inline textField(
-        constText*label,
-        char* b,
-        idx_t sz,
-        char* const* v,
-        action a=doNothing,
-        eventMask e=noEvent,
-        styles style=noStyle,
-        systemStyles ss=(Menu::systemStyles)(_noStyle|_canNav|_parentDraw)
-      ):navTarget(*new textFieldShadow(label,b,sz,v,a,e,style,ss)) {}
-      inline char* buffer() const {return ((textFieldShadow*)shadow)->_buffer();}
-      inline idx_t sz() const {return ((textFieldShadow*)shadow)->_sz();}
-      constText* validator(int i);
-      void parseInput(navNode& nav,menuIn& in) override;
-      void doNav(navNode& nav,navCmd cmd) override;
-      Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override;
-      #ifdef MENU_FMT_WRAPS
-        virtual classes type() const;
-      #endif
-      #ifdef MENU_ASYNC
-        bool async(const char*uri,navRoot& root,idx_t lvl) override;
-        const char* typeName() const override;
-      #endif
-    };
-
-    //--------------------------------------------------------------------------
-    //using this fieldBase saves 418 flash bytes per field template instantiation
-    class fieldBase:public navTarget {
-      public:
-        bool tunning=false;
-        inline fieldBase(constMEM promptShadow& shadow):navTarget(shadow) {}
-        #ifdef MENU_FMT_WRAPS
-          virtual classes type() const;
-        #endif
-        #ifdef MENU_ASYNC
-          bool async(const char*uri,navRoot& root,idx_t lvl) override;
-        #endif
-        inline constText* units() {return ((fieldBaseShadow*)shadow)->_units();}
-        void doNav(navNode& nav,navCmd cmd) override;
-        virtual bool canTune()=0;
-        virtual void constrainField()=0;
-        virtual void stepit(int increment)=0;
-        virtual idx_t printReflex(menuOut& o) const =0;
-        Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override;
-        #ifdef MENU_ASYNC
-          const char* typeName() const override;
-        #endif
-    };
-    //--------------------------------------------------------------------------
-    template<typename T>
-    class menuField:public fieldBase {
-      public:
-        T reflex;
-        menuField(constMEM menuFieldShadow<T> & shadow):fieldBase(shadow) {}
-        menuField(
-          T &value,
-          constText* text,
-          constText*units,
-          T low,
-          T high,
-          T step,
-          T tune,
-          action a=doNothing,
-          eventMask e=noEvent,
-          styles s=noStyle
-        ):menuField(*new menuFieldShadow<T>(value,text,units,low,high,step,tune,a,e,s)) {}
-        bool canTune() override;
-        void constrainField() override;
-        idx_t printReflex(menuOut& o) const override;
-        void parseInput(navNode& nav,menuIn& in) override;
-        Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override;
-        inline T& target() const {return ((menuFieldShadow<T>*)shadow)->target();}
-        inline T getTypeValue(constMEM T* from) const {return ((menuFieldShadow<T>*)shadow)->getTypeValue(from);}
-        inline T low() const {return  ((menuFieldShadow<T>*)shadow)->_low();}
-        inline T high() const {return ((menuFieldShadow<T>*)shadow)->_high();}
-        inline T step() const {return ((menuFieldShadow<T>*)shadow)->_step();}
-        inline T tune() const {return ((menuFieldShadow<T>*)shadow)->_tune();}
-        void clearChanged(const navNode &nav,const menuOut& out,bool sub) override;
-        bool changed(const navNode &nav,const menuOut& out,bool sub=true,bool test=false) override;
-        void stepit(int dir) override;
-        #ifdef MENU_ASYNC
-          void printValue(menuOut& o) const override;
-          void printHigh(menuOut& o) const override;
-          void printLow(menuOut& o) const override;
-          void printStep(menuOut& o) const override;
-          void printTune(menuOut& o) const override;
-          const char* typeName() const override;
-        #endif
-      };
-
-    //--------------------------------------------------------------------------
-    template<typename T>
-    class menuValue:public prompt {
-      public:
-        inline menuValue(constMEM menuValueShadow<T>& shadow):prompt(shadow) {}
-        inline menuValue(constText* text,T value,action a=doNothing,eventMask e=noEvent)
-          :menuValue(*new menuValueShadow<T>(text,value,a,e)) {}
-        inline T target() const {return ((menuValueShadow<T>*)shadow)->target();}
-        #ifdef MENU_FMT_WRAPS
-          virtual classes type() const {return valueClass;}
-        #endif
-        #ifdef MENU_ASYNC
-          bool async(const char*uri,navRoot& root,idx_t lvl=0) override;
-          const char* typeName() const override;
-        #endif
-    };
-
-    //--------------------------------------------------------------------------
-    class menuNode:public navTarget {
-      public:
-        inline menuNode(constMEM menuNodeShadow& s):navTarget(s) {}
-        inline menuNode(constText* text,idx_t sz,prompt* constMEM data[],action a=noAction,eventMask e=noEvent,styles style=wrapStyle,systemStyles ss=(systemStyles)(_menuData|_canNav))
-          :navTarget(*new menuNodeShadow(text,sz,data,a,e,style,ss)) {}
-        #ifdef MENU_FMT_WRAPS
-          virtual classes type() const;
-        #endif
-        virtual prompt& operator[](idx_t i) const {return ((menuNodeShadow*)shadow)->operator[](i);}
-        bool changed(const navNode &nav,const menuOut& out,bool sub=true,bool test=false) override;
-        void clearChanged(const navNode &nav,const menuOut& out,bool sub) override;
-        inline idx_t sz() const {return ((menuNodeShadow*)shadow)->_sz();}
-        inline prompt* constMEM* data() const {return ((menuNodeShadow*)shadow)->_data();}
-        #ifdef MENU_USERAM
-          void swap(idx_t a,idx_t b) {
-            if (has(_menuData)) {//ignore on virtual data menus
-              auto ops=((menuNodeShadow*)shadow)->_data();
-              auto tmp=ops[a];
-              ops[a]=ops[b];
-              ops[b]=tmp;
-            }
-          }
-        #endif
-        // #ifdef MENU_ASYNC
-        //   prompt* seek(idx_t* uri,idx_t len) override;
-        // #endif
-        #ifdef MENU_ASYNC
-          bool async(const char*uri,navRoot& root,idx_t lvl=0) override;
-          const char* typeName() const override;
-          //aux function, parse uri node (text to idx_t)
-          idx_t parseUriNode(const char*&uri);
-        #endif
-        template<bool clear>
-        bool _changes(const navNode &nav,const menuOut& out,bool sub,bool test);
-    };
-
-    //--------------------------------------------------------------------------
-    class menu:public menuNode {
-      public:
-        inline menu(constMEM menuNodeShadow& shadow):menuNode(shadow) {}
-        // Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override {
-        // }
-        #ifdef MENU_ASYNC
-          const char* typeName() const override;
-        #endif
-    };
-
-    //--------------------------------------------------------------------------
-    class menuVariantBase:public menuNode {
-      public:
-        inline menuVariantBase(constMEM menuNodeShadow& s):menuNode(s) {}
-        virtual idx_t sync()=0;
-        virtual idx_t sync(idx_t i)=0;
-        Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override;
-        idx_t togglePrintTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr);
-        void doNav(navNode& nav,navCmd cmd) override;
-        #ifdef MENU_ASYNC
-          const char* typeName() const override;
-        #endif
-    };
-    template<typename T>
-    class menuVariant:public menuVariantBase {
-      public:
-        idx_t reflex;
-        inline menuVariant(constMEM menuNodeShadow& s):menuVariantBase(s) {}
-        inline menuVariant(constText* text,T &target,idx_t sz,prompt* constMEM* data,action a,eventMask e,styles style)
-          :menuVariantBase(*new menuVariantShadow<T>(text,target,sz,data,a,e,style)) {}
-        idx_t sync() override;
-        idx_t sync(idx_t i) override;
-        inline T& target() const {return ((menuVariantShadow<T>*)shadow)->target();}
-        bool changed(const navNode &nav,const menuOut& out,bool sub=true,bool test=false) override;
-        #ifdef MENU_ASYNC
-          idx_t selected() const override;
-          const char* typeName() const override;
-        #endif
-    };
-
-    template<typename T>//-------------------------------------------
-    class select:public menuVariant<T> {
-      public:
-        inline select(constMEM menuNodeShadow& s):menuVariant<T>(s) {}
-        inline select(
-          constText* text,
-          T &target,
-          idx_t sz,
-          prompt* constMEM* data,
-          action a=doNothing,
-          eventMask e=noEvent,
-          styles style=noStyle,
-          systemStyles ss=((systemStyles)(Menu::_menuData|Menu::_canNav|Menu::_isVariant|Menu::_parentDraw))
-        ):menuVariant<T>(*new menuVariantShadow<T>(text,target,sz,data,a,e,style,ss)) {}
-        #ifdef MENU_FMT_WRAPS
-          virtual classes type() const {return selectClass;}
-        #endif
-        #ifdef MENU_ASYNC
-          const char* typeName() const override {return "select";}
-        #endif
-    };
-
-    template<typename T>//-------------------------------------------
-    class toggle:public menuVariant<T> {
-      public:
-        inline toggle(constMEM menuNodeShadow& s):menuVariant<T>(s) {}
-        inline toggle(
-          constText* text,
-          T &target,
-          idx_t sz,
-          prompt* constMEM* data,
-          action a=doNothing,
-          eventMask e=noEvent,
-          styles style=noStyle,
-          systemStyles ss=((systemStyles)(Menu::_menuData|Menu::_isVariant))
-        ):menuVariant<T>(*new menuVariantShadow<T>(text,target,sz,data,a,e,style,ss)) {}
-        #ifdef MENU_FMT_WRAPS
-          classes type() const override;
-        #endif
-        Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override;
-        result sysHandler(SYS_FUNC_PARAMS) override;
-        #ifdef MENU_ASYNC
-          const char* typeName() const override;
-          bool async(const char*uri,navRoot& root,idx_t lvl) override;
-        #endif
-    };
-
-    template<typename T>//-------------------------------------------
-    class choose:public menuVariant<T> {
-      public:
-        inline choose(constMEM menuNodeShadow& s):menuVariant<T>(s) {}
-        inline choose(
-          constText* text,
-          T &target,
-          idx_t sz,
-          prompt* constMEM* data,
-          action a=doNothing,
-          eventMask e=noEvent,
-          styles style=noStyle,
-          systemStyles ss=((systemStyles)(Menu::_menuData|Menu::_canNav|Menu::_isVariant))
-        ):menuVariant<T>(*new menuVariantShadow<T>(text,target,sz,data,a,e,style,ss)) {}
-        #ifdef MENU_FMT_WRAPS
-          classes type() const override;
-        #endif
-        Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override;
-        result sysHandler(SYS_FUNC_PARAMS) override;
-        bool changed(const navNode &nav,const menuOut& out,bool sub=true,bool test=false) override;
-        #ifdef MENU_ASYNC
-          const char* typeName() const override;
-        #endif
-    };
-
-  }
-
-#endif
diff --git a/src/itemsTemplates.cpp b/src/itemsTemplates.cpp
deleted file mode 100644
index 6fc14c72..00000000
--- a/src/itemsTemplates.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#pragma once
-
-#include "menuDefs.h"
-
-////////////////////////////////////////////////////////////////////////
-// template implementation
-#include "menuIo.h"
-#include "nav.h"
-namespace Menu {
-
-  #ifdef MENU_ASYNC
-    template<typename T>
-    bool menuValue<T>::async(const char*uri,navRoot& root,idx_t lvl) {
-      trace(MENU_DEBUG_OUT<<(*(prompt*)this)<<" menuValue::async! lvl:"<<lvl<<" navRoot.level:"<<root.level<<" navFocus:"<<(*(prompt*)root.navFocus)<<endl);
-      return prompt::async(uri,root,lvl);
-    }
-    template<typename T>
-    const char* menuValue<T>::typeName() const {return "menuValue";}
-  #endif
-
-  template<typename T>
-  bool menuField<T>::canTune() {return !!tune();}
-  template<typename T>
-  void menuField<T>::constrainField() {target() = constrain(target(), low(), high());}
-  template<typename T>
-  void menuField<T>::clearChanged(const navNode &nav,const menuOut& out,bool sub) {
-    fieldBase::clearChanged(nav,out,sub);
-    reflex=target();
-  }
-  template<typename T>
-  bool menuField<T>::changed(const navNode &nav,const menuOut& out,bool sub,bool test) {
-    trace(if (test&&dirty) MENU_DEBUG_OUT<<"field dirty"<<endl);
-    trace(if (test&&(reflex!=target())) MENU_DEBUG_OUT<<"reflex!=target reflex:"<<reflex<<" target:"<<target()<<endl);
-    return dirty||(reflex!=target());
-  }
-
-  template<typename T>
-  idx_t menuField<T>::printReflex(menuOut& o) const {return o.print(reflex);}
-
-  template<typename T>
-  Used menuField<T>::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-    trace(print_P(out,getText());MENU_DEBUG_OUT<<" menuField<T>::printTo "<<reflex<<endl);
-    reflex=target();
-    return fieldBase::printTo(root,sel,out,idx,len,panelNr);
-  }
-
-  template<typename T>
-  void menuField<T>::parseInput(navNode& nav,menuIn& in) {
-    //TODO: on a cmd based nav (not streams) this mess will be pushed to stream input only
-    //can not enter negative number literals by serial, using steps or web is ok
-    bool neg=false;
-    char nc=in.peek();
-    if (nc=='-') {
-      in.read();
-      if (!strchr(numericChars,in.peek())) {
-        doNav(nav,downCmd);
-        return;
-      }
-      // Serial.println("NEGATIVE NUMBER PARSE THEN!");
-      neg=true;
-    }
-    if (neg||strchr(numericChars,nc)) {//a numeric value was entered
-      if (in.numValueInput) {
-        target()=(T)((neg?-1:1)*in.parseFloat());//TODO: use template specialization and proper convertion
-        tunning=true;
-        doNav(nav,enterCmd);
-      } else doNav(nav,idxCmd);
-    } else doNav(nav,nav.navKeys(in.read()));
-  }
-
-  #ifdef MENU_ASYNC
-    template<typename T>
-    void menuField<T>::printValue(menuOut& o) const {o.print(reflex);}
-    template<typename T>
-    void menuField<T>::printHigh(menuOut& o) const {o.print(high());}
-    template<typename T>
-    void menuField<T>::printLow(menuOut& o) const {o.print(low());}
-    template<typename T>
-    void menuField<T>::printStep(menuOut& o) const {o.print(step());}
-    template<typename T>
-    void menuField<T>::printTune(menuOut& o) const {o.print(tune());}
-    template<typename T>
-    const char* menuField<T>::typeName() const {return typeStr<T>();};
-  #endif
-
-  template<typename T>
-  void menuField<T>::stepit(int dir) {
-    dir*=options->invertFieldKeys?-1:1;
-    T thisstep = tunning?tune():step();
-    dirty=true;
-    //by default they are inverted.. now buttons and joystick have to flip them
-    if (dir > 0) {
-      if ((high()-target()) < thisstep)
-        target() = canWrap()?low():high();
-      else
-        target() += thisstep;
-    } else {
-      if ((target()-low()) < thisstep)
-        target() = canWrap()?high():low();
-      else
-        target() -= thisstep;
-    }
-  }
-
-  template<typename T>
-  Used choose<T>::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-    bool ed=this==root.navFocus;
-    return ed?
-      prompt::printTo(root,sel,out,idx,len,panelNr)
-      :menuVariantBase::printTo(root,sel,out,idx,len,panelNr);
-  }
-
-  template<typename T>
-  Used toggle<T>::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) {
-    return menuVariantBase::togglePrintTo(root,sel,out,idx,len,panelNr);
-  }
-
-  #ifdef MENU_ASYNC
-    template<typename T>
-    const char* toggle<T>::typeName() const {return "toggle";}
-    template<typename T>
-    bool toggle<T>::async(const char*uri,navRoot& root,idx_t lvl) {
-      _trace(MENU_DEBUG_OUT<<(*(prompt*)this)<<" toggle::async! uri:"<<uri<<endl);
-      if(uri[0]) {
-        _trace(Serial<<"selecting value by index!"<<endl);
-        idx_t n=menuNode::parseUriNode(uri);
-        _trace(MENU_DEBUG_OUT<<"n:"<<n<<" sel:"<<root.path[lvl].sel<<endl);
-        menuVariant<T>::sync(n);//sync to index n!
-        // root.node().event(root.useUpdateEvent?updateEvent:enterEvent);
-        return true;
-      }
-      //if not by index then do the toggle
-      _trace(Serial<<"toggle proceed..."<<endl);
-      // root.doNav(navCmd(enterCmd));
-      // return true;
-      // bool r=prompt::async(uri,root,lvl);
-      // root.node().event(root.useUpdateEvent?updateEvent:enterEvent);
-      // return r;
-      return prompt::async(uri,root,lvl);
-    }
-  #endif
-
-  template<typename T>
-  result toggle<T>::sysHandler(SYS_FUNC_PARAMS) {
-    _trace(Serial<<"toggle sysHandler!"<<endl;);
-    switch(event) {
-        case activateEvent: {
-        idx_t at=menuVariant<T>::sync();
-        assert(at!=-1);
-        at++;
-        if (at>=menuNode::sz()) at=0;
-        menuVariant<T>::sync(at);
-        prompt::dirty=true;
-        (menuNode::operator[](at))(FUNC_VALUES);
-      }
-      default:
-        return proceed;
-    }
-  }
-
-  #ifdef MENU_FMT_WRAPS
-    template<typename T>
-    classes toggle<T>::type() const {return toggleClass;}
-  #endif
-
-  template<typename T>
-  idx_t menuVariant<T>::sync() {
-    for(idx_t i=0;i<sz();i++)
-      if (((menuValue<T>*)&operator[](i))->target()==target()) return i;
-    #ifdef MENU_DEBUG
-      MENU_DEBUG_OUT.print("value out of range ");
-      MENU_DEBUG_OUT.println(target());MENU_DEBUG_OUT.flush();
-      assert(false);
-    #endif
-    return -1;
-  }
-  template<typename T>
-  idx_t menuVariant<T>::sync(idx_t i) {
-    #ifdef MENU_DEBUG
-      if (!(i>=0&&i<sz())){
-        print_P(MENU_DEBUG_OUT,getText());
-        MENU_DEBUG_OUT.print(" : value out of range ");
-        MENU_DEBUG_OUT.println(i);
-      }
-      assert(i>=0&&i<sz());
-    #endif
-    if (i!=reflex) dirty=true;
-    reflex=i;
-    target()=((menuValue<T>*)&operator[](i))->target();
-    return i;
-  }
-
-  template<typename T>
-  bool menuVariant<T>::changed(const navNode &nav,const menuOut& out,bool sub,bool test) {
-    return dirty||((menuValue<T>*)&operator[](reflex))->target()!=target();
-  }
-
-  #ifdef MENU_ASYNC
-    template<typename T>
-    idx_t menuVariant<T>::selected() const {return reflex;}
-    template<typename T>
-    const char* menuVariant<T>::typeName() const {return "menuVariant";}
-  #endif
-
-  template<typename T>
-  result choose<T>::sysHandler(SYS_FUNC_PARAMS) {
-    switch(event) {
-      case updateEvent:
-      case enterEvent:
-        nav.sel=menuVariant<T>::sync();
-      default:
-        return proceed;
-    }
-  }
-
-  template<typename T>
-  bool choose<T>::changed(const navNode &nav,const menuOut& out,bool sub,bool test) {
-    return menuVariant<T>::changed(nav,out)||menuNode::changed(nav,out);
-  }
-
-  #ifdef MENU_FMT_WRAPS
-    template<typename T>
-    classes choose<T>::type() const {return chooseClass;}
-  #endif
-
-  #ifdef MENU_ASYNC
-    template<typename T>
-    const char* choose<T>::typeName() const {return "choose";}
-  #endif
-
-}//namespace Menu
diff --git a/src/macros.h b/src/macros.h
deleted file mode 100644
index 70246e27..00000000
--- a/src/macros.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/* -*- C++ -*- */
-#include "baseMacros.h"
-
-//#define MENU_USERAM
-
-//////////////////////////////////////////////////////////////////////////////
-// memory macros ------------------------------------------------------------
-#ifndef __AVR_ARCH__
-  #define MENU_USERAM
-#endif
-#if defined(ESP8266)
-  #define MENU_ASYNC
-  #define MENU_FMT_WRAPS
-  #define MENU_IDLE_BKGND
-#endif
-#if defined(ESP8266) | defined(CORE_TEENSY)
-  #define typeof(x) __typeof__(x)
-#endif
-#if defined(USE_PGM) || (defined(pgm_read_ptr_near) && !defined(MENU_USERAM))
-  //storing some values into avr flash memory (saving ram space)
-  #ifdef MENU_DEBUG
-    #warning "Using PGM"
-  #endif
-  #define USING_PGM
-  #define MEMMODE PROGMEM
-  #define constMEM const
-  #define constText const char
-  #define memPtr(src) pgm_read_ptr(&(src))
-  #define memByte(addr) (pgm_read_byte(addr))
-  #define memWord(addr) (pgm_read_word(addr))
-  #define memIdx(src) (pgm_read_byte(&src))
-  #define memStrLen strlen_P
-  #define memEnum(addr) (sizeof(int)==1?memByte(addr):memWord(addr))
-#else
-  //use ram on non-avr devices or when explicit
-  #ifdef MENU_DEBUG
-    #warning "Using RAM"
-  #endif
-  #define USING_RAM
-  #define MEMMODE
-  #define constMEM
-  #define constText char
-  #define memPtr(src) (src)
-  #define memByte(addr) (*addr)
-  #define memWord(addr) (*addr)
-  #define memIdx(src) (src)
-  #define memStrLen strlen
-  #define memEnum(addr) (*addr)
-  // #ifndef F
-    #define F(x) (x)
-  // #endif
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// menu structure macros
-#define DECL(x) DECL_##x
-#define DEF(x) DEF_##x,
-
-#define PANELS(id,...)\
-  constMEM panel _panels_##id[] MEMMODE={__VA_ARGS__};\
-  Menu::navNode* _nodes_##id[sizeof(_panels_##id)/sizeof(panel)];\
-  Menu::panelsList id(_panels_##id,_nodes_##id,sizeof(_panels_##id)/sizeof(panel));
-
-#define MENU_OUTLIST(id,...)\
-  Menu::menuOut* constMEM _outputs_##id[] MEMMODE ={__VA_ARGS__};\
-  Menu::outputsList id(_outputs_##id,sizeof(_outputs_##id)/sizeof(Menu::menuOut*));
-
-#define MENU_INPUTS(id,...)\
-  menuIn* _inputs_##id[]={__VA_ARGS__};\
-  Menu::chainStream<sizeof(_inputs_##id)/sizeof(menuIn*)> id(_inputs_##id);
-
-//some aux macros to define structures
-#define SWAP(a,b,...) b,a,__VA_ARGS__
-#define CALL(a,b) CALL_(HEAD_##a,HEAD_##b,TAIL_##a,TAIL_##b)
-#define HEAD_ON(n,...) n
-#define TAIL_ON(a,...) __VA_ARGS__
-#define HEAD_WITH(n,...) n
-#define TAIL_WITH(a,...) __VA_ARGS__
-#define CALL_(...) CALL__(__VA_ARGS__)
-#define CALL__(a,b,...) a##_##b(__VA_ARGS__)
-
-#define SERIAL_OUT(...) ON(SERIAL_OUT,__COUNTER__,__VA_ARGS__)
-#define ANSISERIAL_OUT(...) ON(ANSISERIAL_OUT,__COUNTER__,__VA_ARGS__)
-#define LIQUIDCRYSTAL_OUT(...) ON(LIQUIDCRYSTAL_OUT,__COUNTER__,__VA_ARGS__)
-#define LCD_OUT(...) ON(LCD_OUT,__COUNTER__,__VA_ARGS__)
-#define ADAGFX_OUT(...) ON(ADAGFX_OUT,__COUNTER__,__VA_ARGS__)
-#define TFT_eSPI_OUT(...) ON(TFT_eSPI_OUT,__COUNTER__,__VA_ARGS__)
-#define TFT_OUT(...) ON(TFT_OUT,__COUNTER__,__VA_ARGS__)
-#define U8GLIB_OUT(...) ON(U8GLIB_OUT,__COUNTER__,__VA_ARGS__)
-#define U8G2_OUT(...) ON(U8G2_OUT,__COUNTER__,__VA_ARGS__)
-#define UART_OUT(...) ON(UART_OUT,__COUNTER__,__VA_ARGS__)
-#define UCG_OUT(...) ON(UCG_OUT,__COUNTER__,__VA_ARGS__)
-#define U8X8_OUT(...) ON(U8X8_OUT,__COUNTER__,__VA_ARGS__)
-#define UTFT_OUT(...) ON(UTFT_OUT,__COUNTER__,__VA_ARGS__)
-#define SSD1306ASCII_OUT(...) ON(SSD1306ASCII_OUT,__COUNTER__,__VA_ARGS__)
-
-#define VAR_HEAD_NONE(...)
-
-///////////////////////////////////////////////////////////////////////////////
-// output device macros
-#define VAR_SERIAL_OUT(id,md,n,port)\
-Menu::idx_t id##Tops##n[md];\
-Menu::serialOut id##n(port,id##Tops##n);
-
-#define VAR_ANSISERIAL_OUT(id,md,n,port,color,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::ansiSerialOut id##n(port,color,id##Tops##n,id##Panels##n);
-
-#define VAR_LIQUIDCRYSTAL_OUT(id,md,n,device,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::liquidCrystalOut id##n(device,id##Tops##n,id##Panels##n);
-
-#define VAR_LCD_OUT(id,md,n,device,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::lcdOut id##n(&device,id##Tops##n,id##Panels##n);
-
-#define VAR_ADAGFX_OUT(id,md,n,gfx,color,fontW,fontH,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::adaGfxOut id##n(gfx,color,id##Tops##n,id##Panels##n,fontW,fontH);
-
-#define VAR_TFT_eSPI_OUT(id,md,n,gfx,color,fontW,fontH,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::TFT_eSPIOut id##n(gfx,color,id##Tops##n,id##Panels##n,fontW,fontH);
-
-#define VAR_TFT_OUT(id,md,n,gfx,color,fontW,fontH,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::TFTOut id##n(gfx,color,id##Tops##n,id##Panels##n,fontW,fontH);
-
-#define VAR_U8GLIB_OUT(id,md,n,gfx,color,fontW,fontH,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::u8gLibOut id##n(gfx,color,id##Tops##n,id##Panels##n,fontW,fontH);
-
-#define VAR_U8G2_OUT(id,md,n,gfx,color,fontW,fontH,offsetX,offsetY,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::u8g2Out id##n(gfx,color,id##Tops##n,id##Panels##n,fontW,fontH,offsetX,offsetY);
-
-#define VAR_UART_OUT(id,md,n,gfx,color,font,offsetX,offsetY,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::uartOut id##n(gfx,color,id##Tops##n,id##Panels##n,font,offsetX,offsetY);
-
-#define VAR_UCG_OUT(id,md,n,gfx,color,fontW,fontH,offsetX,offsetY,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::UCGLibOut id##n(gfx,color,id##Tops##n,id##Panels##n,fontW,fontH,offsetX,offsetY);
-
-#define VAR_U8X8_OUT(id,md,n,gfx,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::U8x8Out id##n(gfx,id##Tops##n,id##Panels##n);
-
-#define VAR_UTFT_OUT(id,md,n,gfx,color,fontW,fontH,...)\
-Menu::idx_t id##Tops##n[md];\
-PANELS(id##Panels##n,__VA_ARGS__);\
-Menu::utftOut id##n(gfx,color,id##Tops##n,id##Panels##n,fontW,fontH);
-
-#define REF_HEAD_NONE(...)
-#define REF_SERIAL_OUT(id,md,n,...) &id##n,
-#define REF_ANSISERIAL_OUT(id,md,n,...) &id##n,
-#define REF_LIQUIDCRYSTAL_OUT(id,md,n,...) &id##n,
-#define REF_LCD_OUT(id,md,n,...) &id##n,
-#define REF_ADAGFX_OUT(id,md,n,...) &id##n,
-#define REF_TFT_eSPI_OUT(id,md,n,...) &id##n,
-#define REF_U8GLIB_OUT(id,md,n,...) &id##n,
-#define REF_U8G2_OUT(id,md,n,...) &id##n,
-#define REF_UART_OUT(id,md,n,...) &id##n,
-#define REF_UCG_OUT(id,md,n,...) &id##n,
-#define REF_U8X8_OUT(id,md,n,...) &id##n,
-#define REF_UTFT_OUT(id,md,n,...) &id##n,
-
-#define MENU_OUTPUTS(id,maxDepth,...)\
-	XFOR_EACH(CALL,WITH(VAR,id,maxDepth),__VA_ARGS__)\
-	Menu::menuOut* constMEM id##_outPtrs[] MEMMODE={\
-	   XFOR_EACH(CALL,WITH(REF,id,maxDepth),__VA_ARGS__)\
-	};\
-Menu::outputsList id(id##_outPtrs,sizeof(id##_outPtrs)/sizeof(Menu::menuOut*));
-
-#define MENU(id,text,aFn,mask,style,...) altMENU(Menu::menu,id,text,aFn,mask,style,(Menu::_menuData|Menu::_canNav),__VA_ARGS__)
-#define PADMENU(id,text,aFn,mask,style,...) altMENU(Menu::menu,id,text,aFn,mask,style,(Menu::_asPad|Menu::_menuData|Menu::_canNav|Menu::_parentDraw),__VA_ARGS__)
-#define altMENU(objType,id,text,aFn,mask,style,ss,...)\
-  FOR_EACH(DECL,__VA_ARGS__)\
-  constText id##_text[] MEMMODE=text;\
-  Menu::prompt* constMEM id##_data[] MEMMODE={\
-    FOR_EACH(DEF,__VA_ARGS__)\
-  };\
-  constMEM MEMMODE Menu::menuNodeShadowRaw id##ShadowRaw={\
-    (Menu::callback)aFn,\
-    (Menu::systemStyles)(ss|Menu::_menuData|Menu::_canNav),\
-    id##_text,\
-    mask,\
-    style,\
-    sizeof(id##_data)/sizeof(Menu::prompt*),\
-    id##_data\
-  };\
-  constMEM Menu::menuNodeShadow& id##Shadow=*(Menu::menuNodeShadow*)&id##ShadowRaw;\
-  objType id(id##Shadow);
-
-#define SELECT(...) altVARIANT(Menu::select,((systemStyles)(Menu::_menuData|Menu::_canNav|Menu::_isVariant|Menu::_parentDraw)),__VA_ARGS__)
-#define CHOOSE(...) altVARIANT(Menu::choose,((systemStyles)(Menu::_menuData|Menu::_canNav|Menu::_isVariant)),__VA_ARGS__)
-#define TOGGLE(...) altVARIANT(Menu::toggle,((systemStyles)(Menu::_menuData|Menu::_isVariant)),__VA_ARGS__)
-#define altVARIANT(objType,ss,target,id,text,action,mask,style,...)\
-  constText id##_text[] MEMMODE=text;\
-  XFOR_EACH(DECL_VALUE,target,__VA_ARGS__)\
-  Menu::prompt* constMEM id##_data[] MEMMODE={\
-    FOR_EACH(DEF,__VA_ARGS__)\
-  };\
-  constMEM MEMMODE Menu::menuVariantShadowRaw<typeof(target)> id##ShadowRaw={\
-    (Menu::callback)action,\
-    ss,\
-    id##_text,\
-    mask,\
-    style,\
-    sizeof(id##_data)/sizeof(prompt*),\
-    id##_data,\
-    &target\
-  };\
-  constMEM MEMMODE Menu::menuVariantShadow<typeof(target)>& id##_Shadow=*(menuVariantShadow<typeof(target)>*)&id##ShadowRaw;\
-  objType<typeof(target)> id (id##_Shadow);
-
-// bridging macros prepending id's to arguments list
-// for all elements that need separate allocation and a name to it
-#define OP(...) altOP(prompt,__VA_ARGS__)
-#define altOP(...) OP_(__COUNTER__,__VA_ARGS__)
-#define EXIT(...) EXIT_(__COUNTER__,__VA_ARGS__)
-#define FIELD(...) altFIELD(Menu::menuField,__VA_ARGS__)
-#define EDIT(...) EDIT_(__COUNTER__,textField,(Menu::systemStyles)(_noStyle|_canNav|_parentDraw),__VA_ARGS__)
-//#define EDIT(editor,...) FIELD_(__COUNTER__,editor,((Menu::systemStyles)(Menu::_canNav)),__VA_ARGS__)
-#define altFIELD(fieldObj,...) FIELD_(__COUNTER__,fieldObj,((Menu::systemStyles)(Menu::_canNav|Menu::_parentDraw)),__VA_ARGS__)
-#define VALUE(...) VALUE_(__COUNTER__,__VA_ARGS__)
-#define ITEM(...) ITEM_(__COUNTER__,__VA_ARGS__)
-#define OBJ(...) OBJ_(__VA_ARGS__)
-#define DEF_OBJ_(o) (&o)
-#define DECL_OBJ_(...)
-
-//allocating space for elements and shadows -------------------------------------
-#define DECL_EXIT_(cnt,exitText)\
-  constText title_##cnt[] MEMMODE=exitText;\
-  constMEM MEMMODE Menu::promptShadowRaw opShadowRaw##cnt = {\
-    (Menu::callback)Menu::doExit,\
-    Menu::_Exit,\
-    title_##cnt,\
-    Menu::enterEvent\
-  };\
-  constMEM Menu::promptShadow& opShadow##cnt=*(Menu::promptShadow*)&opShadowRaw##cnt;\
-  Menu::prompt op##cnt(opShadow##cnt);
-#define DECL_ITEM_(cnt,objType,text,aFn,mask,ss,...) \
-  constText title_##cnt[] MEMMODE=text;\
-  constMEM MEMMODE Menu::promptShadowRaw opShadowRaw##cnt={\
-    (Menu::callback)aFn,\
-    ss,\
-    title_##cnt,\
-    mask,\
-    noStyle\
-  };\
-  constMEM Menu::promptShadow& opShadow##cnt=*(promptShadow*)&opShadowRaw##cnt;\
-  objType op##cnt(opShadow##cnt,__VA_ARGS__);
-#define DECL_OP_(cnt,objType,text,aFn,mask) \
-  constText title_##cnt[] MEMMODE=text;\
-  constMEM MEMMODE Menu::promptShadowRaw opShadowRaw##cnt={\
-    (Menu::callback)aFn,\
-    _noStyle,\
-    title_##cnt,\
-    mask,\
-    noStyle\
-  };\
-  constMEM Menu::promptShadow& opShadow##cnt=*(promptShadow*)&opShadowRaw##cnt;\
-  objType op##cnt(opShadow##cnt);
-#define DECL_FIELD_(cnt,objType,ss,target,text,units,low,high,step,tune,action,mask,style)\
-  constText fieldLabel##cnt[] MEMMODE=text;\
-  constText fieldUnit##cnt[] MEMMODE=units;\
-  constMEM MEMMODE Menu::menuFieldShadowRaw<typeof(target)> fieldShadowRaw##cnt={\
-    (Menu::callback)action,\
-    ss,\
-    fieldLabel##cnt,\
-    mask,\
-    style,\
-    fieldUnit##cnt,\
-    &target,\
-    low,\
-    high,\
-    step,\
-    tune\
-  };\
-  constMEM Menu::menuFieldShadow<typeof(target)>& _fieldShadow##cnt=*(Menu::menuFieldShadow<typeof(target)>*)&fieldShadowRaw##cnt;\
-  objType<typeof(target)> _menuField##cnt(_fieldShadow##cnt);
-#define DECL_EDIT_(cnt,objType,ss,label,buf,valid,action,mask,style)\
-  constText textFieldLabel##cnt[] MEMMODE=label;\
-  constMEM MEMMODE Menu::textFieldShadowRaw textFieldShadowRaw##cnt={\
-    (Menu::callback)action,\
-    ss,\
-    textFieldLabel##cnt,\
-    mask,\
-    style,\
-    buf,\
-    valid,\
-    sizeof(valid)/sizeof(char*)\
-  };\
-  constMEM Menu::textFieldShadow& _fieldShadow##cnt=*(Menu::textFieldShadow*)&textFieldShadowRaw##cnt;\
-  objType _textField##cnt(_fieldShadow##cnt);
-#define DECL_SUBMENU(id)
-#define DECL_VALUE(target,...) MK_VALUE(target, _##__VA_ARGS__)
-#define _VALUE_(...)  __VA_ARGS__
-#define DEF_VALUEOBJ(x) &x
-#define GET_VALUE(_1,_2,_3,_4,_5,_6,NAME,...) NAME
-#define IGNORE(...)
-#define MK_VALUE(...) GET_VALUE(__VA_ARGS__,_MK_VALUE,_MK_VALUE,_MK_VALUE,_MK_VALUE,IGNORE,_MK_VALUE)(__VA_ARGS__)
-#define _MK_VALUE(target,cnt,text,value,action,mask)\
-  constText valueLabel##cnt[] MEMMODE=text;\
-  constMEM MEMMODE Menu::menuValueShadowRaw<typeof(target)> choice##cnt##ShadowRaw={\
-    (Menu::callback)action,\
-    Menu::_noStyle,\
-    valueLabel##cnt,\
-    mask,\
-    Menu::noStyle,\
-    value\
-  };\
-  constMEM Menu::menuValueShadow<typeof(target)>& choice##cnt##Shadow=\
-    *(menuValueShadow<typeof(target)>*)&choice##cnt##ShadowRaw;\
-  Menu::menuValue<typeof(target)> menuValue##cnt(choice##cnt##Shadow);
-
-// when building a list of elements --------------------------------------------
-#define DEF_EXIT_(cnt,...) &op##cnt
-#define DEF_OP_(cnt,...) &op##cnt
-#define DEF_FIELD_(cnt,...) &_menuField##cnt
-#define DEF_EDIT_(cnt,...) &_textField##cnt
-#define DEF_SUBMENU(id) &id
-#define DEF_VALUE(id) &id
-#define DEF_VALUE_(cnt,...) &menuValue##cnt
-#define DEF_ITEM_(cnt,...) &op##cnt
-
-//The navigation root ------------------------------------------------------------------
-#define NAVROOT(id,menu,maxDepth,in,out)\
-  Menu::navNode id##_path[maxDepth];\
-  Menu::navRoot id(menu,id##_path,maxDepth,in,out);
-
-//use zero length outputs list instead
-//#define NO_INPUTS_NAV (*(Stream*)NULL)
-//#define NO_OUTPUTS_NAV (*(outputsList*)NULL)
diff --git a/src/menu.cpp b/src/menu.cpp
deleted file mode 100644
index c3ff1641..00000000
--- a/src/menu.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#include "menuDefs.h"
-using namespace Menu;
-
-const char* Menu::numericChars="0123456789.";
-
-result Menu::doNothing() {return proceed;}
-result Menu::doExit() {return quit;}
-action Menu::noAction(doNothing);
-
-//this is for idle (menu suspended)
-result Menu::inaction(menuOut& o,idleEvent) {
-  trace(MENU_DEBUG_OUT<<"Menu::inaction"<<endl);
-  return proceed;
-}
-
-result Menu::maxDepthError(menuOut& o,idleEvent e) {
-  trace(MENU_DEBUG_OUT<<"maxDepthError"<<endl);
-  o.print("Error: maxDepth reached!\n\rincrease maxDepth on your scketch.");
-  return proceed;
-}
-
-#if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-  String& operator<<(String&s,prompt &p) {return s+=p.getText();}
-  Stream& operator<<(Stream&o,prompt& p) {print_P(o,p.getText());return o;}
-  Print& operator<<(Print&o,prompt& p) {print_P(o,p.getText());return o;}
-#endif
diff --git a/src/menu.h b/src/menu.h
index ad44d874..8e0c5557 100644
--- a/src/menu.h
+++ b/src/menu.h
@@ -1,17 +1,53 @@
 /* -*- C++ -*- */
-/********************
-Sept 2014 ~ Oct. 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
+#pragma once
+/**
+* @author Rui Azevedo
+* @brief ArduinoMenu main include file
 
-menu library for the arduino framework
+This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
+This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
 
-www.r-site.net
+#include "menu/sys/staticMenu.h"
+#include "menu/sys/components.h"
+#include "menu/sys/fields.h"
+#include "menu/fmt/xml.h"
+#include "menu/fmt/text.h"
+#include "menu/nav.h"
+#include "menu/item.h"
+#include "menu/IO/Arduino/rfIn.hpp"
 
-creative commons license 4.0: CC BY-NC-SA
-This software is furnished "as is", without technical support, and with no
-warranty, express or implied, as to its usefulness for any purpose.
-***/
-#pragma once
+namespace Menu {
+  template<typename Cfg>
+  struct ConfigMenuLib {
+    template<typename O>
+    using CP=typename Cfg::template Part<O>;
+    template<template<typename> class... I>
+    using ItemDef=ItemDefBase<CP,I...>;
+    template<template<typename> class... I>
+    using InDef=InDefBase<CP,I...>;\
+    template<template<typename> class... I>
+    using OutDef=OutDefBase<CP,I...>;
+    template<template<typename> class... I>
+    using NavDef=NavDefBase<CP,I...>;
+  };
+};
+
+#define CONFIG_MENU_LIB(Cfg)\
+  using MenuLib=Menu::ConfigMenuLib<Cfg>;\
+  template<template<typename> class... I>\
+  using ItemDef=MenuLib::ItemDef<I...>;\
+  template<template<typename> class... I>\
+  using InDef=MenuLib::InDef<I...>;\
+  template<template<typename> class... I>\
+  using OutDef=MenuLib::OutDef<I...>;\
+  template<template<typename> class... I>\
+  using NavDef=MenuLib::NavDef<I...>;
 
-#include "menuDefs.h"
 
-#include "itemsTemplates.cpp"
+#if defined(RS_DEBUG)&&!defined(RELEASE)
+// namespace Menu {
+//   MDO mdo;
+// };
+#endif
diff --git a/src/menu/IO/AM4Keys.h b/src/menu/IO/AM4Keys.h
new file mode 100644
index 00000000..fc4c9d4d
--- /dev/null
+++ b/src/menu/IO/AM4Keys.h
@@ -0,0 +1,32 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "../sys/base.h"
+
+namespace Menu {
+
+  struct AM4Parser {
+    template<typename In>
+    struct Part:In {
+      using Base=In;
+      using This=Part<In>;
+      using Base::Base;
+      Part(const This&)=delete;
+      Part& operator=(const This&)=delete;
+      // static constexpr bool isParser=true;
+      template<typename Nav>
+      bool parseCmd(Nav& nav,Key k,bool e=false) {
+        bool r;
+        switch(k) {
+          case '+': r=nav.template cmd<Cmd::Up>();break;
+          case '-': r=nav.template cmd<Cmd::Down>();break;
+          case '*': r=nav.template cmd<Cmd::Enter>();break;
+          case '/': r=nav.template cmd<Cmd::Esc>();break;
+          default:  r=nav.template cmd<Cmd::KeyCode>(k);break;
+        }
+        return r||In::parseCmd(nav,k,e);
+      }
+    };
+  };
+
+};
diff --git a/src/menu/IO/Arduino/UC1609TextOut.h b/src/menu/IO/Arduino/UC1609TextOut.h
new file mode 100644
index 00000000..6bf0b792
--- /dev/null
+++ b/src/menu/IO/Arduino/UC1609TextOut.h
@@ -0,0 +1,69 @@
+/* -*- C++ -*- */
+#pragma once
+
+#ifdef ARDUINO
+  #include <ERM19264_UC1609.h>
+  #include "../../out.h"
+
+  namespace Menu {
+
+    struct UC1609TextFmt {
+      template<typename O=Void<>>
+      struct Part:O {
+        using Base=O;
+        using This=Part<O>;
+        using Base::Base;
+        template<Fmt tag,bool start> 
+        void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {
+          // if(start) fmt<tag,start>(editing,tunning,n,sel,en);
+          // if(tag==Fmt::Item&&!start) Base::cl();
+          // if(!start) 
+          // fmt<tag,start>(editing,tunning,n,sel,en);
+        }
+      };
+    };
+    template<typename Dev,Dev& dev,int fontx,int fonty,int lcdwidth,int lcdheight>
+    struct UC1609TextOutBase {
+      template<typename O>
+      struct Part:O {
+        using Base=O;
+        using Base::Base;
+        using This=Part<O>;
+        Idx cx,cy;
+        void newView() {
+          cx=0;
+          cy=0;
+          dev.LCDNoBufferGotoXY(0,0);
+          Base::newView();
+        }
+        void write(const char* o,int len){
+          for(int n=0;n<len&&cx<lcdwidth;cx++,n++)
+            dev.LCDNoBufferChar(o[n]);
+        }
+        void cl() {
+          for(;cx<lcdwidth;cx++)
+            dev.LCDNoBufferChar(' ');
+        }
+        template<typename Data>
+        void print(Data o) {
+          String d(o);
+          write(d.c_str(),d.length());
+        }
+        void nl() {
+          cl();
+          cx=0;
+          dev.LCDNoBufferGotoXY(0,++cy);
+          Base::nl();
+        }
+      };
+    };
+    
+    template<typename Dev,Dev& dev,int fontx=7,int fonty=9,int lcdwidth=192/fontx,int lcdheight=64/fonty>
+    using UC1609TextOut=Chain<
+      UC1609TextFmt::template Part,
+      UC1609TextOutBase<Dev,dev,fontx,fonty,lcdwidth,lcdheight>::template Part
+    >;
+
+
+  };//Menu namespace
+#endif
\ No newline at end of file
diff --git a/src/menu/IO/Arduino/rfIn.h b/src/menu/IO/Arduino/rfIn.h
new file mode 100644
index 00000000..80537379
--- /dev/null
+++ b/src/menu/IO/Arduino/rfIn.h
@@ -0,0 +1,190 @@
+#pragma once
+
+#include "menu/in.h"
+#include <debug.h>
+using namespace Parts;
+
+#include "../../tinyTimeUtils/src/tinyTimeUtils.h"
+using namespace TinyTimeUtils;
+
+namespace Menu {
+
+  // this can be done:
+  // 1) within menu options => scan structure to build shell
+  // 2) as a separate list
+  // => use both!
+  // radio will not use this, we wil use old fashion switch case
+  //commands base
+  // struct Command {
+  //   template<typename O>
+  //   struct Part {
+  //     using Base=O;
+  //     using This=Part<Base>;
+  //     using Base::Base;
+  //   };
+  // };
+  
+  //radio command id
+  // template<Idx _code,bool _repeat=true>
+  // struct CmdCode {
+  //   static constexpr Idx code() {return _code;}
+  //   static constexpr Idx repeat() {return _repeat;}
+  //   static bool codeIs(Idx i) {return i==code();}
+  //   // template<typename O>
+  //   // struct Part:O {
+  //     // using Base=O;
+  //     // using This=Part<Base>;
+  //     // using Base::Base;
+  //   // };
+  // };
+  //
+  // union CmdCode {
+  //   inline CmdCode(uint8_t o):raw(o) {}
+  //   uint8_t raw;
+  //   struct {
+  //     uint8_t code:7;
+  //     uint8_t repeat:1;
+  //   };
+  // };
+  //
+  //shell command definition
+  //TODO:
+  //  how to match text?
+  //  how to define params
+  //  menu options can all be commands, so do we need this as item part?
+  //  we do need this for non menu ralated commands => separate list
+  // struct ShellCmd {
+  //   struct Int {};
+  //   struct Float {};
+  //   struct Str {};
+  //   template<typename O>
+  //   struct Part:O {
+  //     using Base=O;
+  //     using This=Part<Base>;
+  //     using Base::Base;
+  //     template<typename M>
+  //     static bool match(M&) {return false;}
+  //     static bool match(ConstText m) {
+  //       return false;
+  //     }      
+  //   };
+  // };
+
+  //use a button for pairing
+  struct ArduinoPairBtn {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      Part(const This&)=delete;
+      Part& operator=(const This&)=delete;
+      bool rcvCmd(unsigned long raw) {
+        // clog<<"pairing:"<<O::PinAPI::get()<<endl;
+        return O::rcvCmd(raw,O::PinAPI::get());
+      }
+    };
+  };
+
+  //lock to remote id (pairing)
+  //idBits: size of id in bits
+  //TODO: make pairId a Value so that we can externally use persistency and remove load/save/storSize from here
+  struct RFIdLock {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      Part(const This&)=delete;
+      Part& operator=(const This&)=delete;
+      static constexpr int idBits=sizeof(typename Base::ValueType)<<3;
+      // static unsigned long pairId;
+      bool rcvCmd(unsigned long raw,bool pair=false) {
+        int ds=O::Type::dataSz();
+        int sz=ds-idBits;
+        unsigned long mask=~(((unsigned long)(~0))<<(ds-idBits));
+        unsigned long idMask=((unsigned long)(~0))>>((sizeof(raw)<<3)-ds);
+        unsigned long id=(raw&idMask)>>sz;
+        if(pair) {
+          _trace(clog<<"RFIdLock::rcvCmd raw: 0x"<<hex<<raw<<endl);
+          _trace(clog<<"RFIdLock::rcvCmd id: 0x"<<hex<<id<<endl);
+          // pairId=id;
+          Base::set(id);
+          _trace(clog<<"RFIdLock::rcvCmd get: 0x"<<hex<<Base::get()<<endl);
+          return true;
+        }
+        // if(id!=Base::get()) return false;
+        return (id==Base::get())&&O::rcvCmd(raw&mask);
+      }
+      //TODO: move save/load out of menu stuff. because menu is not dealing with persistency
+      // template<typename M>
+      // bool save(M& midia) {
+      //   // _trace(clog<<"RFIdLock::save 0x"<<hex<<pairId<<endl);
+      //   _trace(clog<<"RFIdLock::save"<<endl);
+      //   return /*midia.write(pairId)&&*/Base::save(midia);
+      // }
+      // template<typename M>
+      // bool load(M& midia) {
+      //   // bool r=midia.read(pairId);
+      //   // _trace(clog<<"RFIdLock::load 0x"<<hex<<pairId<<endl);
+      //   _trace(clog<<"RFIdLock::load"<<endl);
+      //   return /*r&&*/Base::load(midia);
+      // }
+      // template<typename M>
+      // inline auto storSize(M& midia)->decltype(Base::storSize(midia)) {
+      //   return /*sizeof(pairId)+*/Base::storSize(midia);
+      // }
+    };    
+  };
+
+  //RF input device, reads command codes and eventually call parser
+  template<int repeatTimeout=100>
+  struct RFIn {
+    template<typename In=Quiet<>>
+    struct Part:In {
+      using Base=In;
+      using This=Part<In>;
+      using Base::Base;
+      Part(const This&)=delete;
+      Part& operator=(const This&)=delete;
+      // static constexpr bool isReader=true;
+      static volatile uint32_t rfCmd;
+      static uint32_t lastCmd;
+      // static Tick<repeatTime> radioRepeat;
+      // static Tick<pauseTimeout> radioPause;
+      static Tick<repeatTimeout> radioTimeout;//must be greater the repeat period
+      //radio receiver callback
+      static bool rcvCmd(unsigned long cmd) {
+        rfCmd=cmd;
+        if(radioTimeout) {
+          lastCmd=0;
+          radioTimeout.reset();
+        } else if(!(lastCmd==cmd&&Base::repeats((uint8_t)cmd)))
+          radioTimeout.reset();
+        // _trace(clog<<"RFIn::rcvCmd: 0x"<<hex<<cmd<<endl);
+        return true;
+      }
+      // void relax() {
+      //   // _trace(clog<<"RFIn::relax"<<endl);
+      //   //allow commands to repeat
+      //   if(radioRepeat) {
+      //     lastCmd=0;
+      //     rfCmd=0;
+      //   }
+      //   if(radioPause) rfCmd=0;
+      //   In::relax();//pass on
+      // }
+      template<typename Nav>
+      inline bool parseKey(Nav& nav) {
+        if(lastCmd!=rfCmd) {
+          // _trace(clog<<"RFin::parseKey: 0x"<<hex<<rfCmd<<endl);
+          lastCmd=rfCmd;
+          return In::parseCmd(nav,lastCmd);
+        }
+        return In::parseKey(nav);
+      }
+    };
+  };
+
+};
+
diff --git a/src/menu/IO/Arduino/rfIn.hpp b/src/menu/IO/Arduino/rfIn.hpp
new file mode 100644
index 00000000..ad337a4d
--- /dev/null
+++ b/src/menu/IO/Arduino/rfIn.hpp
@@ -0,0 +1,29 @@
+#include "rfIn.h"
+
+namespace Menu {
+
+  template<int repeatTimeout>
+  template<typename In>
+  volatile uint32_t RFIn<repeatTimeout>::Part<In>::rfCmd;
+
+  template<int repeatTimeout>
+  template<typename In>
+  uint32_t RFIn<repeatTimeout>::Part<In>::lastCmd;
+
+  // template<int repeatTime,int pauseTimeout>
+  // template<typename In>
+  // Tick<repeatTime> RFIn<repeatTime,pauseTimeout>::Part<In>::radioRepeat;
+
+  // template<int repeatTime,int pauseTimeout>
+  // template<typename In>
+  // Tick<pauseTimeout> RFIn<repeatTime,pauseTimeout>::Part<In>::radioPause;
+
+  template<int repeatTimeout>
+  template<typename In>
+  Tick<repeatTimeout> RFIn<repeatTimeout>::Part<In>::radioTimeout;
+
+  // template<int idBits,int handlerId>
+  // template<typename O>
+  // unsigned long RFIdLock<idBits,handlerId>::Part<O>::pairId=0;
+};
+
diff --git a/src/menuIO/serialIO.h b/src/menu/IO/Arduino/serialIO.h
similarity index 52%
rename from src/menuIO/serialIO.h
rename to src/menu/IO/Arduino/serialIO.h
index 9c5a4df1..4e16512e 100644
--- a/src/menuIO/serialIO.h
+++ b/src/menu/IO/Arduino/serialIO.h
@@ -1,3 +1,5 @@
 /* -*- C++ -*- */
+#pragma once
+
 #include "serialIn.h"
-#include "serialOut.h"
+#include "serialOut.h"
\ No newline at end of file
diff --git a/src/menu/IO/Arduino/serialIn.h b/src/menu/IO/Arduino/serialIn.h
new file mode 100644
index 00000000..054eeaef
--- /dev/null
+++ b/src/menu/IO/Arduino/serialIn.h
@@ -0,0 +1,28 @@
+/* -*- C++ -*- */
+#pragma once
+
+#ifdef ARDUINO
+  #include "../../sys/base.h"
+
+  namespace Menu {
+
+    //Arduino serial input reader
+    template<typename Dev,Dev& dev>
+    struct SerialIn {
+      template<typename In>
+      struct Part:In {
+        static constexpr bool isReader=true;
+        template<typename Nav>
+        inline bool parseKey(Nav& nav) {
+          return dev.available()&&In::parseCmd(nav,dev.read());
+        }
+      };
+    };
+
+    //defaults to Arduino `Serial` as input device
+    template<decltype(Serial)& dev=Serial>
+    using ArduinoSerialIn=SerialIn<decltype(Serial),dev>;
+
+
+  };
+#endif
\ No newline at end of file
diff --git a/src/menu/IO/Arduino/serialOut.h b/src/menu/IO/Arduino/serialOut.h
new file mode 100644
index 00000000..4b4d0f05
--- /dev/null
+++ b/src/menu/IO/Arduino/serialOut.h
@@ -0,0 +1,19 @@
+/* -*- C++ -*- */
+#pragma once
+
+namespace Menu {
+  template<typename Dev,Dev& dev>
+  struct SerialOut {
+    template<typename O>
+    struct Part:O {
+      void write(const char* o,Idx len){dev.write(o,len);}
+      template<typename Data,typename... Args>
+      void print(Data o,Args... args) {
+        // _trace(clog<<"SerialOut::print "<<o<<endl);
+        dev.print(o,args...);
+      }
+      void nl() {dev.println();}
+    };
+  };
+
+};//Menu namespace
diff --git a/src/menu/IO/linuxKeyIn.h b/src/menu/IO/linuxKeyIn.h
new file mode 100644
index 00000000..760d9249
--- /dev/null
+++ b/src/menu/IO/linuxKeyIn.h
@@ -0,0 +1,65 @@
+/* -*- C++ -*- */
+#pragma once
+
+//POSIX PC Keyboard
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/select.h>
+#include <termios.h>
+#include "menu/in.h"
+
+namespace Menu {
+  struct termios orig_termios;
+
+  void reset_terminal_mode() {tcsetattr(0, TCSANOW, &orig_termios);}
+
+  void set_conio_terminal_mode() {
+      struct termios new_termios;
+      tcgetattr(0, &orig_termios);
+      memcpy(&new_termios, &orig_termios, sizeof(new_termios));
+      atexit(reset_terminal_mode);
+      cfmakeraw(&new_termios);
+      tcsetattr(0, TCSANOW, &new_termios);
+  }
+
+  int kbhit() {
+    struct timeval tv = { 0L, 0L };
+    fd_set fds;
+    FD_ZERO(&fds);
+    FD_SET(0, &fds);
+    return select(1, &fds, NULL, NULL, &tv);
+  }
+
+  int getch() {
+    unsigned char c;
+    int r=read(0, &c, sizeof(c));
+    return r<0?r:c;
+  }
+
+  //POSIX system key reader
+  struct LinuxKeyIn {
+    template<typename In=Quiet<>>
+    struct Part:In {
+      static constexpr bool isReader=true;
+      inline Part() {set_conio_terminal_mode();}//capture the keyboard
+      inline ~Part() {reset_terminal_mode();}//reset the capture state
+      template<typename Nav>
+      inline bool parseKey(Nav& nav) {
+        if(!kbhit()) return In::parseKey(nav);
+        bool ext=false;
+        int k=getch();
+        if (k==3) {
+          //preemptive handle Ctrl+C
+          reset_terminal_mode();
+          exit(0);
+        }
+        if (k==27&&kbhit()) {
+          ext=true;
+          k=getch();
+        }
+        return In::parseCmd(nav,k,ext);
+      }
+    };
+  };
+};
diff --git a/src/menu/IO/outList.h b/src/menu/IO/outList.h
new file mode 100644
index 00000000..c2b5d1ea
--- /dev/null
+++ b/src/menu/IO/outList.h
@@ -0,0 +1,32 @@
+#pragma once
+
+namespace Menu {
+  //a list of output devices
+  template<typename O,typename... OO>
+  struct OutList:StaticMenuBody<O,OO...> {
+    // using _tail=OutList<OO...>;
+    using Base=StaticMenuBody<O,OO...>;
+    using Base::head;
+    inline void begin() {
+      Base::head().begin();
+      Base::tail().begin();
+    }
+    inline void nl() {
+      Base::head().nl();
+      Base::tail().nl();
+    }
+    inline void newView() {
+      Base::head().newView();
+      Base::tail().newView();
+    }
+    template<typename Nav,typename Menu>
+    void printMenu(Nav& nav,Menu& menu,Idx level,Idx selIdx) {
+      Base::head().template printMenu<Nav,Menu>(nav,menu,level,selIdx);
+      Base::tail().template printMenu<Nav,Menu>(nav,menu,level,selIdx);
+    }
+  };
+
+  template<typename O>
+  struct OutList<O>:O {};
+
+}//namespace Menu
\ No newline at end of file
diff --git a/src/menu/IO/pcArrows.h b/src/menu/IO/pcArrows.h
new file mode 100644
index 00000000..623552ed
--- /dev/null
+++ b/src/menu/IO/pcArrows.h
@@ -0,0 +1,29 @@
+/* -*- C++ -*- */
+#pragma once
+
+//POSIX PC Keyboard
+#include "menu/in.h"
+namespace Menu {
+  //PC keyboard arrows to menu commands
+  struct PCArrows {
+    template<typename In>
+    struct Part:In {
+      static constexpr bool isParser=true;
+      template<typename Nav>
+      bool parseCmd(Nav& nav,Key k,bool e=false) {
+        if (e&&k==91) return false;//wait for ext code
+        bool r;
+        switch(k) {
+          case 66: r=nav.template cmd<Cmd::Up>();break;
+          case 65: r=nav.template cmd<Cmd::Down>();break;
+          case 13: r=nav.template cmd<Cmd::Enter>();break;
+          case 27: r=nav.template cmd<Cmd::Esc>();break;
+          case 67: r=nav.template cmd<Cmd::Right>();break;
+          case 68: r=nav.template cmd<Cmd::Left>();break;
+          default: r=nav.template cmd<Cmd::KeyCode>(k);break;
+        }
+        return r||In::parseCmd(nav,k,e);
+      }
+    };
+  };
+};
\ No newline at end of file
diff --git a/src/menu/IO/stdOut.h b/src/menu/IO/stdOut.h
new file mode 100644
index 00000000..30c49703
--- /dev/null
+++ b/src/menu/IO/stdOut.h
@@ -0,0 +1,9 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include <iostream>
+#include "streamOut.h"
+
+namespace Menu {
+  struct StdOut:StreamOut<decltype(std::cout),std::cout> {};
+};
\ No newline at end of file
diff --git a/src/menu/IO/streamOut.h b/src/menu/IO/streamOut.h
new file mode 100644
index 00000000..9c1681f3
--- /dev/null
+++ b/src/menu/IO/streamOut.h
@@ -0,0 +1,17 @@
+/* -*- C++ -*- */
+#pragma once
+
+namespace Menu {
+  
+  template<typename Dev,Dev& dev>
+  struct StreamOut {
+    template<typename O>
+    struct Part:O {
+      void write(const char* o,Idx len){dev.write(o,len);}
+      template<typename Data>
+      void print(Data o,bool toPrint=true) {dev<<o;dev.flush();}
+      void nl() {dev<<"\r\n";}
+    };
+  };
+
+};//Menu namespace
diff --git a/src/menu/arrayMenu.h b/src/menu/arrayMenu.h
new file mode 100644
index 00000000..1c482b3e
--- /dev/null
+++ b/src/menu/arrayMenu.h
@@ -0,0 +1,77 @@
+#pragma once
+/**
+* @author Rui Azevedo
+* @brief C array menu
+*/
+
+#include <menu/item.h>
+
+namespace Menu {
+  template<typename I,Idx size>
+  struct ArrayMenu {
+    template<typename O>
+    struct Part:O {
+      using This=Part<O>;
+      using Base=O;
+      using Base::Base;
+      using ArrayItem=Prompt::template Part<I>*;
+      ArrayItem data[size];
+      Part(ArrayItem data[]):data(data) {}
+      static constexpr Style styles() {return Style::IsMenu|Base::styles();}
+      constexpr Idx sz() const {return size;}
+      ArrayItem& operator[](size_t i) {return data[i]; }
+
+      template<typename API,typename... Args>
+      void forAll(Args... args) {
+        for(Idx i=0;i<size;i++)
+          API().operator()(*data[i],args...);
+      }
+
+      template<typename Target,Idx o,Idx... oo>
+      struct Walk {
+        Target& target;
+        Walk(Target& t):target(t) {}
+        template<typename API,typename... Args>
+        auto walk(Args... args) 
+          ->decltype(
+            Walk<IItem,oo...>(*target[0]).template walk<API,Args...>(args...)
+          ){
+          return Walk<IItem,oo...>(*target[o]).template walk<API,Args...>(args...);
+        }
+      };
+
+      template<typename Target,Idx o>
+      struct Walk<Target,o> {
+        Target& target;
+        Walk(Target& t):target(t) {}
+        template<typename API,typename... Args>
+        auto walk(Args... args) 
+          ->decltype(
+            API().operator()(*(target[o]),args...)
+          ){
+          return API().operator()(*(target[o]),args...);
+        }
+      };
+
+      struct RefWalk {
+        Idx pathLen;
+        const Idx* path;
+        RefWalk(Idx l,Idx* p):pathLen(l),path(p) {}
+        RefWalk(const RefWalk& p):pathLen(p.len()),path(p.path) {}
+        Idx len() const {return pathLen;}
+        Idx head() {return path[0];}
+        RefWalk tail() {return RefWalk(len()-1,(Idx*)&path[1]);}
+        template<typename Target,typename API,typename... Args>
+        auto step(Idx at,Target& target,Args... args) 
+          ->decltype(API().operator()(*target[0],args...))
+          {
+          return len()?
+            RefWalk(pathLen-1,(Idx*)&path[1])
+              .template step<decltype(*target[at]),API,Args...>(head(),*target[at],args...):
+            API().operator()(*target[at],args...);
+        }
+      };
+
+    };
+  };
+};
\ No newline at end of file
diff --git a/src/menu/fmt/ansiFmt.h b/src/menu/fmt/ansiFmt.h
new file mode 100644
index 00000000..7604e0ec
--- /dev/null
+++ b/src/menu/fmt/ansiFmt.h
@@ -0,0 +1,62 @@
+/* -*- C++ -*- */
+#pragma once
+/**
+* @author Rui Azevedo
+* @date 10 May 2019
+* @copyright 2020 Rui Azevedo
+* @brief ArduinoMenu ANSI terminal output
+*/
+
+#include "extra/ansiCodes.h"
+
+namespace Menu {
+	struct AnsiFmt {
+		template<typename O>
+		struct Part:O {
+			using Base=O;
+			using This=Part<O>;
+			using Base::Base;
+			template<bool toPrint=true>
+			inline void clrLine(Idx nr) {
+				if(toPrint) ansiFill(O::orgX(),nr,O::orgX()+O::width(),nr)(*this);
+				setCursor(O::orgX(),nr);
+			}
+			inline void setCursor(int x,int y) {xy(x,y)(*this);}
+		  template<bool io,bool toPrint=true>
+		  inline void fmtPanel(Idx n=0,bool s=false,bool e=true,Mode m=Mode::Normal) {
+				if (io) {
+					setCursor(O::orgX(),O::orgY());
+					setBackgroundColor(BLUE)(*this);
+					setForegroundColor(WHITE)(*this);
+					boldOn()(*this);
+					if (toPrint)
+						ansiFill(O::orgX(),O::orgY(),O::orgX()+O::width(),O::orgY()+O::height())(*this);
+					O::template fmtPanel<io,toPrint>(n,s,e,m);
+				} else {
+					O::template fmtPanel<io,toPrint>(n,s,e,m);
+					boldOff()(*this);
+					defaultForeground()(*this);
+					defaultBackground()(*this);
+				}
+				setCursor(O::orgX(),O::orgY());
+		  }
+		  template<bool io,bool toPrint=true>
+		  inline void fmtMenu(Idx n=0,bool s=false,bool e=true,Mode m=Mode::Normal) {
+				if (io) {
+					hideCursor()(*this);
+					setBackgroundColor(BLUE)(*this);
+					setForegroundColor(WHITE)(*this);
+					boldOn()(*this);
+				} else {
+					O::template fmtMenu<io,toPrint>(n,s,e,m);
+					boldOff()(*this);
+					defaultForeground()(*this);
+					defaultBackground()(*this);
+					// showCursor()(*this);
+					setCursor(0,0);
+				}
+				// setCursor(O::orgX(),O::orgY());
+		  }
+		};
+	};
+};
diff --git a/src/menu/fmt/extra/ansiCodes.h b/src/menu/fmt/extra/ansiCodes.h
new file mode 100644
index 00000000..aaccfddd
--- /dev/null
+++ b/src/menu/fmt/extra/ansiCodes.h
@@ -0,0 +1,217 @@
+/* -*- C++ -*- */
+#pragma once
+
+namespace ANSI {
+	#define ESCAPE 0x1B
+	#define BRACE '['
+	#define BLACK 0
+	#define RED 1
+	#define	GREEN 2
+	#define YELLOW 3
+	#define BLUE 4
+	#define MAGENTA 5
+	#define CYAN 6
+	#define WHITE 7
+	#define BOLD_ON 1
+	#define BOLD_OFF 22
+	#define UNDERLINE_ON 4
+	#define UNDERLINE_OFF 24
+	#define ITALICS_ON 3
+	#define ITALICS_OFF 23
+	#define STRIKETHROUGH_ON 9
+	#define STRIKETHROUGH_OFF 29
+	#define INVERSE_ON 7
+	#define INVERSE_OFF 27
+	#define RESET 1
+	#define DEFAULT_FOREGROUND 39
+	#define DEFAULT_BACKGROUND 49
+
+	struct preamble {
+		template<typename Out>
+		Out& operator()(Out& out) {
+			out.raw((char)ESCAPE);
+			out.raw(BRACE);
+			return out;
+		}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o,preamble cmd) { return cmd(o); }
+
+	struct preambleAndNumberAndValue {
+		int x;char v;
+		preambleAndNumberAndValue(int x, char v):x(x),v(v) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) {
+			out<<preamble();
+			out.raw(x);
+			out.raw(v);
+			return out;
+		}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, preambleAndNumberAndValue cmd) { return cmd(o); }
+
+	struct cursorOp {
+		char v;
+		cursorOp(char v):v(v) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) {
+			out<<preamble();
+			out.raw('?');
+			out.raw(25);
+			out.raw(v);
+			return out;
+		}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, cursorOp cmd) { return cmd(o); }
+
+	struct setAttribute {
+		int a;
+		setAttribute(int a):a(a) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<preambleAndNumberAndValue(a, 'm');}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const setAttribute cmd) { return cmd(o); }
+
+	struct home {
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<preamble()<<'H';}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const home cmd) { return cmd(o); }
+
+	struct xy {
+		int x,y;
+		inline xy(int x, int y):x(x),y(y) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {
+			out<<preamble();
+			out.raw(y);
+			out.raw(';');
+			out.raw(x);
+			out.raw('H');
+			return out;
+		}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const xy cmd) { return cmd(o); }
+
+	struct up {
+		int x;
+		inline up(int x=1):x(x){}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<preambleAndNumberAndValue(x,'A');}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const up cmd) { return cmd(o); }
+
+	struct down {
+		int x;
+		inline down(int x=1):x(x) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<preambleAndNumberAndValue(x,'B');}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const down cmd) { return cmd(o); }
+
+	struct forward {
+		int x;
+		inline forward(int x=1):x(x) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<preambleAndNumberAndValue(x,'C');}
+	};
+
+	struct backward {
+		int x;
+		inline backward(int x=1):x(x) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<preambleAndNumberAndValue(x,'D');}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const backward cmd) { return cmd(o); }
+
+	struct eraseLine {
+		template<typename Out>
+		inline Out& operator()(Out& out) const {
+			out<<preamble();
+			out.raw('2');
+			out.raw('K');
+			return out;
+		}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const eraseLine cmd) { return cmd(o); }
+
+	struct eraseScreen {
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<preamble()<<'1'<<'J';}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const eraseScreen cmd) { return cmd(o); }
+
+	struct setBackgroundColor {
+		int color;
+		inline setBackgroundColor(int color):color(color) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<setAttribute(color + 40);}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const setBackgroundColor cmd) { return cmd(o); }
+
+	struct setForegroundColor {
+		int color;
+		inline setForegroundColor(int color):color(color) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<setAttribute(color + 30);}
+	};
+	template<typename Out>
+	inline Out& operator<<(Out& &o, const setForegroundColor cmd) { return cmd(o); }
+
+	struct ansiFill {
+		int x1, y1, x2, y2;
+		char ch;
+		inline ansiFill(int x1, int y1, int x2, int y2,char ch=' '):x1(x1),y1(y1),x2(x2),y2(y2),ch(ch) {}
+		template<typename Out>
+		inline Out& operator()(Out& out) const {
+			for (int y = y1; y <= y2; y++) {
+				xy(x1,y)(out);
+				for (int x = x1; x <= x2; x++) out.raw(ch);
+			}
+			return out;
+		}
+	};
+
+	template<char c>
+	struct attr {
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<setAttribute(c);}
+	};
+	template<typename Out,char c>
+	inline Out& operator<<(Out& &o, const attr<c> cmd) { return cmd(o); }
+
+	struct hideCursor {
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<cursorOp('h');}
+	};
+
+	struct showCursor {
+		template<typename Out>
+		inline Out& operator()(Out& out) const {return out<<cursorOp('l');}
+	};
+
+	typedef attr<BOLD_ON> boldOn;
+	typedef attr<BOLD_OFF> boldOff;
+	typedef attr<ITALICS_ON> italicsOn;
+	typedef attr<ITALICS_OFF> italicsOff;
+	typedef attr<UNDERLINE_ON> underlineOn;
+	typedef attr<UNDERLINE_OFF> underlineOff;
+	typedef attr<STRIKETHROUGH_ON> strikethroughOn;
+	typedef attr<STRIKETHROUGH_OFF> strikethroughOff;
+	typedef attr<INVERSE_ON> inverseOn;
+	typedef attr<INVERSE_OFF> inverseOff;
+	typedef attr<RESET> reset;
+	typedef attr<DEFAULT_BACKGROUND> defaultBackground;
+	typedef attr<DEFAULT_FOREGROUND> defaultForeground;
+};//namespace ANSI
\ No newline at end of file
diff --git a/src/menu/fmt/text.h b/src/menu/fmt/text.h
new file mode 100644
index 00000000..6e4036e4
--- /dev/null
+++ b/src/menu/fmt/text.h
@@ -0,0 +1,128 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "../out.h"
+
+namespace Menu {
+
+  //reflect nav. edit state using cursor chars
+  template<char none,char edit,char tune>
+  struct EditMode {
+    template<typename O=Empty<Nil>>
+    struct Part:O {
+      using Base=O;
+      using This=Part<Base>;
+      using Base::Base;
+      template<Fmt tag,bool start> 
+      void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {
+        if(tag==Fmt::EditMode) {
+          if(start) {
+            Base::template fmt<tag,start>(editing,tunning,n,sel,en,preview);
+            if(Base::padding()/*&&!preview*/) {
+              if(editing&&sel) Base::print(tunning?tune:edit);
+            } else Base::print((editing&&sel)?(tunning?tune:edit):none);
+          } else Base::template fmt<tag,start>(editing,tunning,n,sel,en,preview);
+        } else Base::template fmt<tag,start>(editing,tunning,n,sel,en,preview);
+      }
+    };
+  };
+
+  //default edit cursors for text mode
+  using TextEditMode=EditMode<' ',':','>'>;
+
+  //print a character before part print
+  template<char prefix='['>
+  struct Prefix {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      template<Fmt tag,bool start> 
+      void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {
+        if(start) Base::print(prefix);
+        Base::template fmt<tag,start>(editing,tunning,n,sel,en);
+      }
+    };
+  };
+
+  //print a character after part print
+  template<char prefix=']'>
+  struct Sufix {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      template<Fmt tag,bool start> 
+      void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {
+        if(!start) Base::print(prefix);
+        Base::template fmt<tag,start>(editing,tunning,n,sel,en);
+      }
+    };
+  };
+
+  //wrap a part printing with prefix and sufix characters
+  template<char prefix='[',char sufix=']'>
+  struct PrintWrap {
+    template<typename O>
+    struct Part:Union<Prefix<prefix>::template Part,Sufix<sufix>::template Part>::template Part<O> {};
+  };
+
+  //conditionally apply a format to a specified part
+  template<Fmt on,template<typename> class Do>
+  struct OnFmt {
+    template<typename O>
+    struct Part:Do<O> {
+      using Base=Do<O>;
+      using This=Part<O>;
+      using Base::Base;
+      template<Fmt tag,bool start> 
+      void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {
+        using Skip=typename Base::Base;
+        if(on==tag) Base::template fmt<tag,start>(editing,tunning,n,sel,en);
+        else Skip::template fmt<tag,start>(editing,tunning,n,sel,en);
+      }
+    };
+  };
+
+  struct TextFmt {
+    template<typename O=Void<>>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      using Base::print;
+      using Base::nl;
+      template<Fmt tag,bool start> 
+      void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {
+        switch(tag) {
+          // case Fmt::EditCursor:
+          //   if(!editing) return;
+          //   if(start) print(tunning?'>':'[');
+          //   else print(tunning?'<':']');
+          //   break;
+          case Fmt::Title:
+            if(!start) {
+              if(Base::padding()) print(" ");
+              else nl();
+            }
+            break;
+          case Fmt::Item:
+            if (start) {
+              if(Base::padding()) {
+                if(sel&&!preview) print(en?'>':'-');
+              } else {
+                print((char)(n<10?'0'+n:' '));
+                print((sel)?(en?'>':'-'):' ');
+              }
+            } else nl();
+            break;
+          default: break;
+        }
+        Base::template fmt<tag,start>(editing,tunning,n,sel,en);
+      }
+    };
+  };
+
+};//Menu namespace
diff --git a/src/menu/fmt/xml.h b/src/menu/fmt/xml.h
new file mode 100644
index 00000000..fa9b2395
--- /dev/null
+++ b/src/menu/fmt/xml.h
@@ -0,0 +1,24 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "../out.h"
+
+namespace Menu {
+  struct XmlFmt {
+    template<typename O=Void<>>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      template<Fmt tag,bool start> 
+      void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {
+        Base::print("<");
+        if(!start) Base::print("/");
+        Base::print(Base::template tagName<tag>());
+        Base::print(">");
+        if(!start) Base::print("\r\n");
+      }
+    };
+  };
+
+};//Menu namespace
diff --git a/src/menu/framework/Arduino/flashText.h b/src/menu/framework/Arduino/flashText.h
new file mode 100644
index 00000000..674e69a1
--- /dev/null
+++ b/src/menu/framework/Arduino/flashText.h
@@ -0,0 +1,48 @@
+#pragma once
+
+namespace Menu {
+  template <const PROGMEM ConstText* text>
+  struct StaticFlashText {
+    template <typename O = Empty<Nil>>
+    struct Part : O {
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &out, int n = 0, bool sel = false) {
+        out.print(text[0]);
+        if (delegate)
+          Base::printTo(nav, out, n, sel);
+      }
+    };
+  };
+
+  struct FlashText {
+    template <typename O = Empty<Nil>>
+    struct Part : O {
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      const ConstText* text;
+      Part(const ConstText* text):text(text) {}
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &out, int n = 0, bool sel = false) {
+        out.print(text[0]);
+        if (delegate)
+          Base::printTo(nav, out, n, sel);
+      }
+    };
+  };
+
+  template <const PROGMEM ConstText* text>
+  struct SCFlashText {
+    template <typename O = Empty<Nil>>
+    struct Part:FlashText::Part<O> {
+      using Base=typename FlashText::Part<O>;
+      Part():Base(text) {}
+    };
+  };
+
+  // template <const PROGMEM ConstText *text>
+  // using FlashLabel = Chain<AsLabel::Part, FlashText<text>::template Part>;
+};
\ No newline at end of file
diff --git a/src/menu/framework/arduino.h b/src/menu/framework/arduino.h
new file mode 100644
index 00000000..8cc4940d
--- /dev/null
+++ b/src/menu/framework/arduino.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "frameworks.h"
+namespace Menu {
+
+  template<typename O=Nil> 
+  struct ArduinoFramework:Framework<O> {
+    inline static uint32_t ms() {return millis();}
+    inline static uint32_t us() {return micros();}
+  };
+  template<typename O=Nil> 
+  struct TinyPlatform:ArduinoFramework<O> {
+    using Idx=byte;
+  };  
+  template<typename O=Nil> 
+  struct DefaultPlatform:ArduinoFramework<O> {
+    using Idx=size_t;
+  };  
+
+};
\ No newline at end of file
diff --git a/src/menu/framework/frameworks.h b/src/menu/framework/frameworks.h
new file mode 100644
index 00000000..9ca6a6e4
--- /dev/null
+++ b/src/menu/framework/frameworks.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "menu/sys/base.h"
+namespace Menu {
+  template<typename O=Nil> 
+  struct Framework:O {
+    inline static constexpr uint32_t ms() {return 0;}
+    inline static constexpr uint32_t us() {return ms()*1000;}
+  };
+};
\ No newline at end of file
diff --git a/src/menu/in.h b/src/menu/in.h
new file mode 100644
index 00000000..cd3cb137
--- /dev/null
+++ b/src/menu/in.h
@@ -0,0 +1,31 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "sys/base.h"
+
+namespace Menu {
+  ////////////////////////////////////////////////////////////////////////////////
+  //basic input, just be quiet
+  template<typename In=Nil>
+  struct Quiet:In {
+    using Base=In;
+    using This=Quiet<In>;
+    using Base::Base;
+    Quiet(const This&)=delete;
+    This& operator=(const This&)=delete;
+    template<typename Dev> inline static void poll(Dev&) {}
+    inline static void begin() {}
+    // inline static void relax() {}
+    inline static constexpr bool action() {return true;}
+    template<typename Nav>
+    inline static constexpr bool parseKey(Nav&) {return false;}
+    template<typename Nav>
+    inline static constexpr bool parseCmd(Nav&,Key,bool=false) {return false;}
+    template<typename Nav>
+    inline bool cmd(Nav& nav,int code=0) {return Base::obj().parseKey(nav);}
+  };
+
+  template<template<typename> class Base,template<typename> class... I>
+  using InDefBase=Composition<Base,I...,Quiet>;
+
+};//menu namespace
\ No newline at end of file
diff --git a/src/menu/item.h b/src/menu/item.h
new file mode 100644
index 00000000..642bff82
--- /dev/null
+++ b/src/menu/item.h
@@ -0,0 +1,242 @@
+/* -*- C++ -*- */
+#pragma once
+
+// #include "sys/kernel/path.h"
+#include "menu/out.h"
+
+namespace Menu {
+
+  //API calls
+  //agensts to call member function on post provided objects
+  APIDEF(get,GetValue);
+  APIDEF(valueIs,ValueIs);
+  APIDEF(isDefault,IsDefault);
+  APIDEF(setDefault,SetDefault);
+  APIDEF(styles,Styles);
+  APIDEF(enabled,Enabled);
+  APIDEF(enable,Enable);
+  // APIDEF(relax,Relax);
+  APIDEF(poll,Poll);
+
+  APIDEF(sz,Sz);
+  APIDEF(onPrintTitleTo,PrintTitleTo);
+  APIDEF(onPrintBodyTo,PrintBodyTo);
+  APIDEF(onPrintItemTo,PrintItemTo);
+  APIDEF(esc,Esc);
+  APIDEF(up,Up);
+  APIDEF(down,Down);
+
+  // APIDEF(printTo,PrintTo);
+  struct PrintTo {
+    // constexpr static const char* named="PrintTo";
+    template<typename T,typename Nav,typename Out>
+    inline auto operator()(T& o,Nav& nav,Out& out,int n=0,bool d=true)
+      ->decltype(o.template printTo<Nav,Out>(nav,out,n,d)) 
+      {return o.template printTo<Nav,Out>(nav,out,n,d);}
+  };
+
+  // APIDEF(onPrintMenuTo,PrintMenuTo);
+  struct PrintMenuTo {
+    // constexpr static const char* named="PrintMenuTo";
+    // _trace(MDO& operator<<(MDO& o) const {return o<<named;});
+    template<typename T,typename Nav,typename Out>
+    inline auto operator()(T& o,Nav& nav,Out& out,Idx level,int n)
+      ->decltype(o.template onPrintMenuTo<Nav,Out>(nav,out,level,n)) 
+      {return o.template onPrintMenuTo<Nav,Out>(nav,out,level,n);}
+  };
+  // _trace(MDO& operator<<(MDO& o,const PrintMenuTo& api) {return api.operator<<(o);});
+
+
+  // APIDEF(enter,Enter);
+  struct Enter {
+    // constexpr static const char* named="Enter";
+    // _trace(MDO& operator<<(MDO& o) const {return o<<named;})
+    template<typename T,typename Nav>
+    inline auto operator()(T& o,Nav& nav)
+      ->decltype(o.template enter<Nav>(nav)) 
+      {return o.template enter<Nav>(nav);}
+  };
+  // _trace(MDO& operator<<(MDO& o,const Enter& api) {return api.operator<<(o);});
+
+  template<Cmd c>
+  struct CmdTo {
+    // constexpr static const char* named="CmdTo";
+    // _trace(MDO& operator<<(MDO& o) const {return o<<named<<"<"<<c<<">";});
+    template<typename T,typename Nav>
+    inline auto operator()(T& o,Nav& nav,int code)
+      ->decltype(o.template cmd<Nav,c>(nav,code)) 
+      {return o.template cmd<Nav,c>(nav,code);}
+  };
+  // _trace(
+  //   template<Cmd c>
+  //   MDO& operator<<(MDO& o,const CmdTo<c>& api) {return api.operator<<(o);}
+  // );
+
+  // #ifdef DEBUG
+  //   template<typename API,typename... Args>
+  //   MDO& operator<<(MDO& o,const Map<API,Args...>& api) {return api.operator<<(o);}
+  // #endif
+
+  // Item API ----------------------------
+  template<typename O=Nil>
+  struct Empty:O {
+    using Target=void;
+    using Base=O;
+    using IsTag=No;
+    using Base::Base;
+    using Head=Empty<O>;
+    using Tail=Empty<O>;
+    Empty(){}
+    Empty(const Empty&)=delete;
+    Empty& operator=(const Empty&)=delete;
+    inline static void setDefault() {}
+    // template<typename Next,typename... Args>
+    // static Next build(Args... args) {return Next(args...);}
+    Tail& head() {return *this;}
+    Tail& tail() {return *this;}
+    // static void names() {_trace(MDO::print("."));}
+    IItem* operator[](size_t i) {assert(false);}
+    inline static constexpr bool get() {return true;}
+    inline static void begin() {}
+    // inline static void relax() {}
+    inline static constexpr bool canWrap() {return false;}
+    template<typename T> constexpr static bool valueIs(T&) {return false;}
+    inline static constexpr bool isTop() {return false;}
+    inline static constexpr Style styles() {return Style::None;}
+    inline static constexpr bool is(Idx mask) {return ((Idx)Base::obj().styles())==mask;}
+    inline static constexpr bool has(Idx mask) {return ((Idx)Base::obj().styles())&mask;}
+    inline static constexpr bool changed() {return false;}
+    inline static constexpr bool enabled() {return true;}
+    inline static void enable(bool b) {}
+    template<typename Dev> inline static void poll(Dev&) {
+      // _trace(
+      //   static TinyTimeUtils::Tick<500> dots;
+      //   if(dots) Serial.write('.')
+      // );
+    }
+    template<typename Nav,typename Out,bool=true> 
+    static void printTo(Nav& nav,Out&,int n=0,bool sel=false) {}
+    template<typename Nav,typename Out> void onPrintMenuTo(Nav& nav,Out& out,Idx level,Idx selIdx) {out.printMenu(nav,O::obj(),level,selIdx);}
+    template<typename Nav,typename Out> void onPrintTitleTo(Nav& nav,Out& out) {out.printTitle(nav,O::obj());}
+    template<typename Nav,typename Out> void onPrintBodyTo(Nav& nav,Out& out,Idx level,Idx selIdx,Idx n)
+      {printTo(nav,out,selIdx,n==selIdx);}
+    template<typename Nav,typename Out> void onPrintItemTo(Nav& nav,Out& out,Idx level,int n,bool sel) 
+      {
+        // _trace(clog<<"Empty::onPrintItemTo->printTo"<<endl;clog.flush());
+        Base::obj().template printTo<Nav,Out>(nav,out,n,sel);}
+    template<typename T> static constexpr bool chkId(T n) {return false;}
+    static constexpr Idx sz() {return 1;}
+    static constexpr Idx _sz() {return 1;}
+    template<typename Nav> constexpr static bool up(Nav&) {return true;}
+    template<typename Nav> constexpr static bool down(Nav&) {return true;}
+    template<typename Nav> constexpr static bool enter(Nav&) {return false;}
+    template<typename Nav> constexpr static bool esc(Nav&) {return false;}
+    template<typename Nav> constexpr static bool left(Nav& nav) {return enter(nav);}
+    template<typename Nav> constexpr static bool right(Nav& nav) {return esc(nav);}
+    template<typename Nav> constexpr static bool key(Nav&,Key) {return false;}
+    inline static constexpr bool action() {return true;}
+    template<typename Nav,Cmd c>
+    bool cmd(Nav& nav,int code=0) {
+      // _trace(clog<<"Empty::cmd->obj()..."<<endl);
+      switch(c) {
+        case Cmd::Enter: return O::obj().enter(nav);
+        case Cmd::Esc: return O::obj().esc(nav);
+        case Cmd::Up: return O::obj().up(nav);
+        case Cmd::Down: return O::obj().down(nav);
+        default: return false;
+      }
+    }
+
+    template<typename API,typename... Args>
+    auto map(Args... args) 
+      ->decltype(API().operator()(*this,args...))
+      {return API().operator()(*this,args...);}
+      
+    template<typename Target,Idx o,Idx... oo>
+    struct Walk {
+      Target& target;
+      Walk(Target& t):target(t) {}
+      template<typename API,typename... Args>
+      auto walk(Args... args) 
+        ->decltype(API().operator()(target,args...)) 
+        {return API().operator()(target,args...);}
+    };
+    struct RefWalk {
+     RefWalk(Idx l,Idx*) {assert(!l);}
+     template<typename Target,typename API,typename... Args>
+      auto step(Idx at,Target& target,Args... args) 
+        ->decltype(API().operator()(target,args...))
+        {return API().operator()(target,args...);}
+    };
+    // template<typename Nav,typename Item>
+    // void printItem(Nav& nav,Item& i,Idx n=0,bool sel=false) {
+    //   _trace(clog<<"Empty::printItem"<<endl);
+    //   i.onPrintItemTo(nav,Base::obj(),n,sel);
+    // }
+};
+
+  template<template<typename> class Base,template<typename> class... I>
+  using ItemDefBase=Composition<Base,I...,Empty>;
+
+  //IItem class
+  //The virtual Item API interface
+  class IItem {
+    public:
+      static void names() {}
+      virtual IItem* operator[](size_t i) {assert(false);return this;}
+      virtual Style styles() const {return Style::None;}
+      virtual bool enabled() const {return true;}
+      virtual void enable(bool) {}
+      virtual bool cmd(INav&,Cmd,int) {return false;}
+      virtual void printTo(INav& nav,IOut&,int=0,bool=false){}
+      virtual void onPrintMenuTo(INav& nav,IOut&,int) {}
+      virtual void onPrintTitleTo(INav& nav,IOut& out) {out.printTitle(nav,*this);}
+      virtual void onPrintBodyTo(INav& nav,IOut& out,Idx,Idx,Idx) {}
+      virtual void onPrintItemTo(INav& nav,IOut& out,int n=0,bool sel=false) {}
+      template<typename Nav,Cmd c> bool cmd(INav& nav,int code=0) {return cmd(nav,c,code);}
+      virtual Idx sz() const {return 1;}
+      template<typename Nav,typename Out,bool=true> 
+      static void printTo(Nav& nav,Out& out,int n=0,bool sel=false)
+        {printTo(nav,out,n);}
+  };
+
+  //Prompt class
+  //encapsulate static item definition for use on dynamic containers
+  class Prompt {
+    public:
+      template<typename I>
+      struct Part:IItem, I {
+      using Base=I;
+      using This=Part<Base>;
+      using Base::Base;
+      using Base::cmd;
+      bool cmd(INav& nav,Cmd c,int code) override {
+        switch(c) {
+          case Cmd::Up: return Base::up(nav);
+          case Cmd::Down: return Base::down(nav);
+          case Cmd::Left: return Base::left(nav);
+          case Cmd::Right: return Base::right(nav);
+          case Cmd::Enter: return Base::enter(nav);
+          case Cmd::Esc: return Base::esc(nav);
+          case Cmd::KeyCode: return Base::key(nav,code);
+          default: return false;
+        }
+      }
+
+      IItem* operator[](size_t i) override {return Base::operator[](i);}
+      Style styles() const override {return Base::styles();}
+      bool enabled() const override {return Base::enabled();}
+      void enable(bool b) {Base::enable(b);}
+      void printTo(INav& nav,IOut& out,int n=0,bool sel=false) override
+        {Base::template printTo<INav,IOut>(nav,out,n,sel);}
+      void onPrintMenuTo(INav& nav,IOut& out,int n) override {out.printMenu(nav,Base::obj(),n);}
+      void onPrintTitleTo(INav& nav,IOut& out) override {Base::onPrintTitleTo(nav,out);}
+      void onPrintBodyTo(INav& nav,IOut& out,Idx level,Idx selIdx,Idx n) override 
+        {Base::onPrintBodyTo(nav,out,level,selIdx,n);}
+      void onPrintItemTo(INav& nav,IOut& out,int n=0,bool sel=false) override 
+        {Base::template onPrintItemTo<INav,IOut>(nav,out,n,sel);}
+      Idx sz() const override {return Base::sz();}
+    };
+  };
+
+};//Menu namespace
diff --git a/src/menu/nav.h b/src/menu/nav.h
new file mode 100644
index 00000000..52359b91
--- /dev/null
+++ b/src/menu/nav.h
@@ -0,0 +1,178 @@
+#pragma once
+
+// #include "sys/kernel/base.h"
+
+namespace Menu {
+  template<typename N=Nil>
+  struct Drift:N {
+    Drift(){}
+    Drift(const Drift&)=delete;
+    Drift& operator=(const Drift&)=delete;
+    template<typename Out>
+    static inline void printTo(Out& out) {}
+    template<typename In>
+    inline bool doInput(In& in) {return in.cmd(N::obj());}
+    template<Cmd c> inline static bool cmd() {return false;}
+    template<typename Dev> inline static void poll(Dev&) {}
+    template<typename Out>
+    static inline Idx printTo_api(Out& out,Idx level,Idx* path,Style s) {
+      out.newView();
+      return level?(has<Style::ParentDraw>(s)?level-1:level):0;
+    }
+  };
+
+  template<typename Data,Idx max_depth=8>
+  struct StaticNav {
+    template<typename O=Drift<>>
+    struct Part:O {
+      using Base=O;
+      using This=Part<Base>;
+      using Base::Base;
+      using MenuType=Data;
+      Data data;
+      Idx path[max_depth]{0};
+      Idx level=0;
+      bool _editing=false;
+      bool _tunning=false;
+      bool wasEdited=false;
+      bool edited() const {return wasEdited;}
+      void edited(bool e) {wasEdited=e;}
+      // Part(Data& data):data(data) {}
+      Part(const Part&)=delete;
+      Part& operator=(const Part&)=delete;
+      template<typename Dev>
+      inline void poll(Dev& dev) {
+        auto ref=PathRef(level+(focus()?1:0),path);
+        ref.template walk<Data,Poll,Dev&>(data,dev);
+        // root().poll(dev);//removed.. not for all tree.. use it for active item only
+      }
+      bool focus() {return _editing;}
+      void focus(bool f) {_editing=f;}
+      inline void begin() {data.begin();}
+      inline Data& root() {return data;}
+      // void relax() {if(_editing) PathRef(level,path).walk<Data,Relax>(data);}
+      template<Idx o,Idx oo,Idx... ooo>
+      void go(Idx n=0) {path[n]=o;go<oo,ooo...>(n+1);}
+      template<Idx o>
+      void go(Idx n=0) {quitEdit();path[n]=o;level=n;}
+      void goRoot() {while(level) esc();}
+      void quitEdit() {focus(false);}
+      bool tune() const {return _tunning;}
+      void tune(bool t) {_tunning=t;}
+      Idx* at() {return &path[level];}
+      Idx pos() const {return path[level];}
+      void pos(Idx at) {path[level]=at;}
+      //get position of item or parent when parent printing
+      Idx ppos() {
+        auto s=PathRef(level,path);
+        Idx l=level?(has<Style::ParentDraw>(s.walk<Data,Styles>(data))?level-1:level):0;
+        return path[l];
+      }
+      template<typename Out>
+      inline void printTo(Out& out) {
+        Idx l=Base::printTo_api(out,level,path,PathRef(level,path).walk<Data,Styles>(data));
+        PathRef(l,path).walk<Data,PrintMenuTo,This&,Out&>(
+          data,
+          *this,
+          out,
+          l-1,
+          path[l]
+        );
+        // _trace(clog<<"Nav::printTo -------------------------------"<<endl);
+        // out.newView();
+        // Style s=PathRef(level,path).walk<Data,Styles>(data);
+        // Idx l=level?(has<Style::ParentDraw>(s)?level-1:level):0;
+        // PathRef(l,path).walk<Data,PrintMenuTo,This&,Out&>(data,*this,out,l-1,path[l]);
+      }
+      using Base::cmd;
+      template<Cmd c>
+      inline bool cmd(int code=0) {
+        //TODO: check changes...
+        auto ref=PathRef(level+(focus()?1:0),path);
+        bool r=ref.template walk<Data,CmdTo<c>,This&,int>(data,*this,code);
+        //enter/esc result reflect open/close will, but from now on it must reflect change->redraw
+        //up/down wil alway refer change->draw
+        return r||c==Cmd::Enter||c==Cmd::Esc;
+      }
+      inline bool up() {return cmd<Cmd::Up>();}
+      inline bool down() {return cmd<Cmd::Down>();}
+      inline bool enter() {return cmd<Cmd::Enter>();}
+      inline bool esc() {return cmd<Cmd::Esc>();}
+      template<Cmd c>
+      bool doNav(Idx len,Style s) {
+        switch(c) {
+          case Cmd::Up: {
+            if(pos()<(len-1)) {
+              pos(pos()+1);
+              return true;
+            } else if(has<Style::WrapNav>(s)) {
+              pos(0);
+              return true;
+            }
+            return false;
+          }
+          case Cmd::Down: 
+            if(pos()>0) {
+              pos(pos()-1);
+              return true;
+            } else if(has<Style::WrapNav>(s)) {
+              pos(len-1);
+              return true;
+            }
+            return false;
+          case Cmd::Enter: {
+            auto ref=PathRef(level+1,path);
+            bool r=ref.template walk<Data,Enter,typename This::Type&>(data,This::obj());
+            bool m=has<Style::IsMenu>(s);
+            bool x=r^m;
+            // r m x
+            // 0 0 0 close
+            // 0 1 1 -
+            // 1 0 1 -
+            // 1 1 0 open
+            return x?
+              (has<Style::IsField>(s)?(focus(true),true):true)
+              :r?open():close();
+          }; break;
+          case Cmd::Esc: return close();
+          default: return false;
+        }
+        return true;
+      }
+      bool childEnabled() {return PathRef(level+1,path).template walk<Data,Enabled>(data);}
+      Style styles() {return PathRef(level,path).template walk<Data,Styles>(data);}
+      bool open(Idx i=0) {
+        if(level>=max_depth||!childEnabled()) return false;
+        level++;//enter new level
+        path[level]=i;//pos. at fst item
+        return true;
+      }
+      bool close() {
+        if(focus()) {
+          focus(false);
+          return true;
+        } else if(level) {
+          level--;
+          return true;
+        }
+        return true;
+      }
+    };
+  };
+
+  class INav {
+    public:
+      virtual bool focus() {return false;}
+      virtual bool tune() {return false;}
+  };
+
+  // class Nav {
+  //   public:
+  //     template<typename N>
+  //     struct Part:INav,N {};
+  // };
+
+  template<template<typename> class Base,template<typename> class... I>
+  using NavDefBase=Composition<Base,I...,Drift>;
+
+};//Menu namespace
\ No newline at end of file
diff --git a/src/menu/out.h b/src/menu/out.h
new file mode 100644
index 00000000..b7a337b9
--- /dev/null
+++ b/src/menu/out.h
@@ -0,0 +1,291 @@
+/* -*- C++ -*- */
+#pragma once
+/*
+output base and virtual cap
+*/
+
+#include "sys/base.h"
+
+namespace Menu {
+
+  //Void class
+  //The inactive output definition 
+  //for static output API
+  template<typename O=Nil>
+  struct Void:O {
+    Void() {}
+    Void(const Void&)=delete;
+    inline static void begin() {}
+    Void& operator=(const Void&)=delete;
+    template<typename Dev> inline static void poll(Dev&) {}
+    inline static void nl() {}
+    inline static void newView() {}
+    inline static void setDefault() {}
+    template<typename Nav,typename Menu>
+    static void printMenu(Nav& nav,Menu& menu,Idx level,Idx selIdx) {}
+    template<typename Nav,typename Item>
+    static void printTitle(Nav& nav,Item& i) {}
+    template<typename Nav,typename Item>
+    void printItem(Nav& nav,Item& i,Idx level,Idx n=0,bool sel=false) {
+      // _trace(clog<<"->onPrintItemTo");
+      i.onPrintItemTo(nav,O::obj(),level,n,sel);
+    }
+    template<Fmt,bool> static void fmt(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false) {}
+    template<Fmt tag> void fmtStart(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false)
+      {O::obj().template fmt<tag,true>(editing,tunning,n,sel,en,preview);}
+    template<Fmt tag> void fmtStop(bool editing,bool tunning,int n=0,bool sel=false,bool en=true,bool preview=false)
+      {O::obj().template fmt<tag,false>(editing,tunning,n,sel,en,preview);}
+    template<Fmt tag>
+    static ConstText tagName() {//we need this for xml (not just debug)
+      switch(tag) {
+        case Fmt::Panel: return "panel";
+        case Fmt::Menu: return "menu";
+        case Fmt::Title: return "title";
+        case Fmt::Body: return "body";
+        case Fmt::Item: return "item";
+        case Fmt::Pad: return "pad";
+        case Fmt::Index: return "index";
+        case Fmt::Accel: return "accel";
+        case Fmt::Cursor: return "cursor";
+        case Fmt::Field: return "field";
+        case Fmt::Label: return "label";
+        case Fmt::EditMode: return "editMode";
+        case Fmt::EditCursor: return "editCursor";
+        case Fmt::Value: return "value";
+        case Fmt::Unit: return "unit";
+        default: return "unknown";
+      }
+    }
+    inline void padOn() {}
+    inline void padOff() {}
+    inline constexpr bool padding() {return false;}
+  };
+
+  //print menu title
+  struct TitlePrinter {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      template<typename Nav,typename Menu>
+      void printMenu(Nav& nav,Menu& menu,Idx level,Idx selIdx) {
+        // _trace(clog<<"TitlePrinter::printMenu"<<endl;clog.flush());
+        menu.onPrintTitleTo(nav,Base::obj());
+        Base::template printMenu<Nav,Menu>(nav,menu,level,selIdx);
+      }
+      template<typename Nav,typename Item>
+      /*static*/ void printTitle(Nav& nav,Item& i) {
+        // _trace(clog<<"TitlePrinter::printTitle"<<endl;clog.flush());
+        Base::template fmtStart<Fmt::Title>(nav.focus(),nav.tune());
+        i.template printTo<Nav,typename This::Type>(nav,Base::obj());
+        Base::template fmtStop<Fmt::Title>(nav.focus(),nav.tune());
+      }
+    };
+  };
+
+  //print menu body
+  struct BodyPrinter {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      template<typename Nav,typename Menu>
+      void printMenu(Nav& nav,Menu& menu,Idx level,Idx selIdx) {
+        _trace(clog<<"BodyPrinter::printMenu"<<endl;clog.flush());
+        Base::template fmtStart<Fmt::Body>(nav.focus(),nav.tune());
+        Base::template printMenu<Nav,Menu>(nav,menu,level,selIdx);
+        menu.onPrintBodyTo(nav,Base::obj(),level,selIdx,0);
+        Base::template fmtStop<Fmt::Body>(nav.focus(),nav.tune());
+      }
+    };
+  };
+
+  struct PadPrinter {
+    template<typename O>
+    struct Part:O {
+      Idx padLevel=0;// => single thread
+      using This=Part<O>;
+      using Base=O;
+      using Base::Base;
+      void padOn() {padLevel++;}
+      void padOff() {padLevel--;}
+      bool padding() {return padLevel>0;}
+      void nl() {if(!padLevel) O::nl();}
+      void _nl() {O::nl();}
+    };
+  };
+
+  //provides aux functions for printing
+  struct BasePrinter {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      template<typename Nav,typename Menu>
+      void printMenu(Nav& nav,Menu& menu,Idx level,bool preview,Idx selIdx=0) {
+        // _trace(clog<<"BasePrinter::printMenu"<<endl;clog.flush());
+        Base::template fmtStart<Fmt::Menu>(nav.focus(),nav.tune());
+        Base::template printMenu<Nav,Menu>(nav,menu,level,selIdx);
+        Base::template fmtStop<Fmt::Menu>(nav.focus(),nav.tune());
+      }
+      template<typename Nav,typename Item>
+      void printItem(Nav& nav,Item& i,Idx level,Idx n=0,bool sel=false) {
+        // _trace(clog<<"BasePrinter::printItem ");
+        bool preview=level>nav.level;
+        Base::template fmtStart<Fmt::Item>(nav.focus(),nav.tune(),n,sel,i.enabled(),preview);
+        Base::printItem(nav,i,level,n,sel);
+        Base::template fmtStop<Fmt::Item>(nav.focus(),nav.tune(),n,sel,i.enabled(),preview);
+      }
+    };
+  };
+
+  //print title and body
+  using FullPrinter=MakePart<TitlePrinter::Part,BodyPrinter::Part,BasePrinter::Part>;
+
+////////////////////////////////
+
+  // struct TextMeasure {
+  //   template<typename O>
+  //   struct Part:O {
+  //     using Base=O;
+  //     using This=Part<O>;
+  //     using Base::Base;
+  //     template<bool toPrint=true>
+  //     void write(const char* o,Idx len){dev.write(o,len);}
+  //     template<typename Data>
+  //     void print(Data o) {dev.print(o);}
+  //     void nl() {dev.println();}
+  //   };
+  // };
+
+///////////////////////////////////////////////////////////////////////////////////
+// panels
+
+  //statically defined area
+  //defined by rectangle x,y,w,h
+  template<Idx x,Idx y,Idx w,Idx h>
+  struct StaticPanel {
+    template<typename O>
+    struct Part:O {
+      constexpr static inline Idx orgX() {return x;}
+      constexpr static inline Idx orgY() {return y;}
+      constexpr static inline Idx width() {return w;}
+      constexpr static inline Idx height() {return h;}
+
+      constexpr static inline Idx posX() {return x;}
+      constexpr static inline Idx posY() {return y;}
+      constexpr static inline Idx freeX() {return w;}
+      constexpr static inline Idx freeY() {return h;}
+      constexpr static inline Idx free() {return w*h;}
+      static inline void useX(Idx ux=1) {}
+      static inline void useY(Idx uy=1) {}
+      static inline void use(Idx ux=1,Idx uy=1) {}
+    };
+  };
+
+  template<typename Unit>
+  struct ViewportTrack {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      //restart the panel
+      inline void newView() {fx=O::width();fy=Base::height();}
+      //device coordinates ---------
+      inline Idx posX() const {return Base::width()-fx;}
+      inline Idx posY() const {return Base::height()-fy;}
+      // get free space ----
+      inline Idx freeX() const {return fx;}
+      inline Idx freeY() const {return fy;}
+      inline Idx free() const {return fx+Base::width()*fy;}
+      // // use space ----
+      inline void useX(Unit ux=1) {
+        if (fx) fx-=ux;
+        else useY();
+      }
+      inline void useY(Unit uy=1) {
+        if (!fy) fx=0;
+        else {
+          fy-=uy;
+          if(uy) fx=O::width();
+        }
+      }
+      template<bool toPrint=true>
+      void write(const char* o,Idx len){
+        if(toPrint) Base::write(o,len);
+        useX(len);
+      }
+      template<typename Data,bool toPrint=true>
+      void print(Data o) {
+        if(toPrint) Base::print(o);
+        
+      }
+      template<bool toPrint=true>
+      void nl() {
+        if(toPrint) Base::nl();
+        useY();
+      }
+      protected:
+      //free space tracking
+      Unit fx=Base::width();
+      Unit fy=Base::height();
+    };
+  };
+
+  template<Idx Sz>
+  struct RangePanel {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      Idx top=0;
+      template<typename Nav,typename Item>
+      void printItem(Nav& nav,Item& i,Idx level,Idx n=0,bool sel=false) {
+        auto pos=nav.ppos();//has<Style::ParentDraw>(i.styles())?nav.ppos():nav.pos();
+        while(pos<top) top--;
+        while(pos>(top+Sz-1)) top++;
+        if(n>=top&&(n-top)<Sz) Base::template printItem<Nav,Item>(nav,i,level,n,sel);
+      }
+    };
+  };
+
+/////////////////////////////////////////////////////////////////////////////////
+// virtual top interface
+
+  //define an output
+  //aglomerate all parts into a single output definition
+  template<template<typename> class Base,template<typename> class... O>
+  using OutDefBase=Composition<Base,O...,Void>;
+
+  class IOut {
+    public:
+      IOut() {}
+      virtual void print(int o){}
+      virtual void print(const char* o){}
+      virtual void printMenu(INav& nav,IItem&,Idx) {}
+      virtual void printTitle(INav& nav,IItem&) {}
+      virtual void printItem(INav& nav,IItem& i,Idx level,Idx n=0,bool sel=false) {}
+  };
+
+  //joins mixins static output composition with the vitual output interface
+  class MenuOut {
+    public:
+      template<typename O>
+      struct Part:IOut, O {
+        using Base=O;
+        using This=Part<Base>;
+        using Base::Base;
+        void print(int o) override {O::print(o);}
+        void print(const char* o) override {O::print(o);}
+        void printMenu(INav& nav,IItem& it,Idx selIdx) override {Base::printMenu(nav,it,selIdx);}
+        void printTitle(INav& nav,IItem& it) override {Base::printTitle(nav,it);}
+        void printItem(INav& nav,IItem& it,Idx level,Idx i=0,bool s=false) override {Base::printItem(nav,it,s);}
+      };
+  };
+
+};//Menu namespace
diff --git a/src/menu/sys/base.h b/src/menu/sys/base.h
new file mode 100644
index 00000000..4aae842e
--- /dev/null
+++ b/src/menu/sys/base.h
@@ -0,0 +1,221 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "../parts/src/parts.h"
+#include <tinyTimeUtils.h>
+#include <debug.h>
+using namespace Parts;
+
+namespace Menu {
+
+  // struct PartsCfg:Parts::DefaultCfg {
+  //   #ifdef Arduino
+  //     using Idx=byte;
+  //   #else
+  //     using Idx=uint16_t;//array size type
+  //   #endif
+  // };
+  // using Idx=typename PartsCfg::Idx;
+  // template<Idx... path>
+  // using Path=Parts::Config<PartsCfg>::Path<path...>;
+  // using PathRef=Parts::Config<PartsCfg>::PathRef;
+  // template<typename Fst,typename Snd>
+  // using Pair=Parts::Config<PartsCfg>::Pair<Fst,Snd>;
+  // template<typename Fst,typename Snd>
+  // using Node=Parts::Config<PartsCfg>::Node<Fst,Snd>;
+
+  //function type to use on actions
+  using ActionFn=bool(*)();
+
+  using Key=int;//key type
+  using ConstText=const char*;
+
+  struct Yes {static constexpr bool value(){return true;}};
+  struct No {static constexpr bool value(){return false;}};
+
+  //commands
+  enum class Cmd:Idx {Enter,Esc,Up,Down,Left,Right,KeyCode};
+
+  //output format
+  using fmt_t=Idx;
+  enum class Fmt:fmt_t {
+    Panel,Menu,Title,Body,Item,Pad,
+    Index,Cursor,Field,
+    Accel,Label,EditMode,EditCursor,Value,Unit
+  };
+
+  //attributes
+  enum class Style:Idx {
+    None=0<<0,//0
+    WrapNav=1<<0,//1
+    ParentDraw=1<<1,//2
+    PadDraw=1<<2,//4
+    IsField=1<<3,//8
+    IsMenu=1<<4//16
+    //  168421
+    //21=10101 = WrapNav | PadDraw | IsMenu
+    //17=10001 = WrapNav | IsMenu
+    //19=10011 = WrapNav | ParentDraw | IsMenu
+    //23=10111 = WrapNav | ParentDraw | PadDraw | IsMenu
+  };
+
+  constexpr Style operator&(Style a,Style b) {return (Style)(((Idx)a)&((Idx)b));}
+  constexpr Style operator|(Style a,Style b) {return (Style)(((Idx)a)|((Idx)b));}
+  constexpr Style operator^(Style a,Style b) {return (Style)(((Idx)a)^((Idx)b));}
+  constexpr Style operator~(Style a) {return (Style)~((Idx)a);}
+  // operator bool(Style o) {return (bool)o;}
+  template<Style mask>
+  bool is(Style s) {return ((Idx)s)==(Idx)mask;}
+  template<Style mask>
+  bool has(Style s) {return ((Idx)s)&(Idx)mask;}
+
+  //navigation wrap (nav behavior)
+  struct WrapNav {
+    template<typename O>
+    struct Part:O {
+      using O::O;
+      static constexpr Style styles() {return O::styles()|Style::WrapNav;}
+    };
+  };
+
+  //style: item should be drawn by the parent when active
+  struct ParentDraw {
+    template<typename O>
+    struct Part:O {
+      using O::O;
+      static constexpr Style styles() {return O::styles()|Style::ParentDraw;}
+    };
+  };
+
+  struct PadDraw {
+    template<typename O>
+    struct Part:O {
+      using O::O;
+      static constexpr Style styles() {return O::styles()|Style::PadDraw;}
+      // template<typename Nav,typename Out>
+      // void onPrintBodyTo(Nav& nav,Out& out,Idx level,Idx selIdx,Idx n)  {
+      //   _trace(clog<<"PadDraw::onPrintBodyTo"<<endl;);
+      //   O::onPrintBodyTo(nav,out,selIdx,n);
+      // }
+      template<typename Nav,typename Out>
+      void onPrintMenuTo(Nav& nav,Out& out,Idx level,Idx selIdx) {
+        // _trace(clog<<"PadDraw::onPrintMenuTo"<<endl;);
+        out.padOn();
+        O::onPrintMenuTo(nav,out,level,selIdx);
+        out.padOff();
+      }
+    };
+  };
+
+  //style: item is a menu
+  struct IsMenu {
+    template<typename O>
+    struct Part:O {
+      using O::O;
+      static constexpr Style styles() {return (/*O::isTop()?Style::None:*/O::styles())|Style::IsMenu;}
+    };
+  };
+
+  //makes a `block` of multiple parts that can be skipped as a single element
+  //because `::Base` will point to the next item after the block
+  template<template<typename> class... OO>
+  struct Union {
+    template<typename O>
+    struct Part:Chain<OO...>::template To<O> {
+      using Base=O;
+    };
+  };
+
+  template<template<typename> class... OO>
+  struct MakePart {
+    template<typename O>
+    struct Part:Chain<OO...>::template To<O> {
+      using Base=typename Chain<OO...>::template To<O>;
+      using This=Part<O>;
+      using Base::Base;
+    };
+  };
+
+  // enum class NavRes:Idx {
+  //   None,//keep nav state
+  //   Pass,//pass command to parent
+  //   // Focus,//open as focus only (no level)
+  //   Open,//open nav level (sub-menu)
+  //   Close,//close nav level
+  //   Draw//keep state and redraw
+  // };
+
+  // template<typename O>
+  // O& operator<<(O& out,NavRes n) {
+  //   switch (n) {
+  //     case NavRes::None: return out<<"None";break;
+  //     case NavRes::Pass: return out<<"Pass";break;
+  //     case NavRes::Open: return out<<"Open";break;
+  //     case NavRes::Close: return out<<"Close";break;
+  //     case NavRes::Draw: return out<<"Draw";break;
+  //     default: return out;
+  //   }
+  // }
+
+  //interfaces
+  class IItem;
+  class IOut;
+  class INav;
+
+  //relational op's
+  // struct RelOp {
+  //   template<typename O>
+  //   inline bool operator!=(const O o) const {return !operator==(o);}
+  //   template<typename O>
+  //   inline bool operator>=(const O o) const {return !operator<(o);}
+  //   template<typename O>
+  //   inline bool operator>(const O o) const {return !(operator==(o)||O::operator<(o));}
+  // };
+
+  // template<size_t n> 
+  // struct Num:RelOp {
+  //   template<size_t m>
+  //   inline bool operator==(const Num<m>) const {return n==m;}
+  //   template<size_t m>
+  //   inline bool operator<(const Num<m>) const {return n<m;}
+  // };
+
+};
+
+// #include "menu/sys/kernel/menuDebug.h"
+// #ifdef RS_DEBUG
+// namespace Parts {
+//   template<typename T>
+//   MDO& operator<<(MDO& mdo,T data) {
+//     MDO::print(data);
+//     return mdo;
+//   }
+
+//   MDO& operator<<(MDO& o,const Style s) {
+//     if(s==Style::None) o<<"|None";
+//     else {
+//       if(has<Style::IsMenu>(s)) o<<"|IsMenu";
+//       if(has<Style::WrapNav>(s)) o<<"|WrapNav";
+//       if(has<Style::ParentDraw>(s)) o<<"|ParentDraw";
+//     }
+//     o<<"|";
+//     // else if(has<Style::IsMenu>(s)) o<<"IsMenu";
+//     return o;
+//   }
+//   MDO& operator<<(MDO& o,const Cmd c) {
+//     switch(c) {
+//       case Cmd::Enter: o<<"Enter";break;
+//       case Cmd::Esc: o<<"Esc";break;
+//       case Cmd::Up: o<<"Up";break;
+//       case Cmd::Down: o<<"Down";break;
+//       case Cmd::Left: o<<"Left";break;
+//       case Cmd::Right: o<<"Right";break;
+//       case Cmd::Key: o<<"Key";break;
+//     }
+//     return o;
+//   }
+
+// };
+// #endif
+
+
diff --git a/src/menu/sys/components.h b/src/menu/sys/components.h
new file mode 100644
index 00000000..1a4bc7b1
--- /dev/null
+++ b/src/menu/sys/components.h
@@ -0,0 +1,325 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "menu/item.h"
+
+namespace Menu
+{
+
+  //emit formatting tag events
+  template <Fmt tag>
+  struct As
+  {
+    template <typename O>
+    struct Part : O
+    {
+      using Base = O;
+      using This = Part<O>;
+      using Base::Base;
+      using IsTag = Yes;
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &out, int n = 0, bool sel = false) {
+        using BaseTag = typename Base::IsTag;
+        out.template fmtStart<tag>(nav.focus(), nav.tune(), n, sel);
+        Base::template printTo<Nav, Out, BaseTag::value() || delegate>(nav, out, n, sel);
+        out.template fmtStop<tag>(nav.focus(), nav.tune(), n, sel);
+        // using SkipBase=typename Base::Base;
+        // if(delegate&&!BaseTag::value())
+        //   SkipBase::template printTo<Nav,Out,true>(nav,out,n,sel);
+      }
+    };
+  };
+
+  using AsPanel = As<Fmt::Panel>;
+  using AsMenu = As<Fmt::Menu>;
+  using AsTitle = As<Fmt::Title>;
+  using AsBody = As<Fmt::Body>;
+  using AsItem = As<Fmt::Item>;
+  using AsPad = As<Fmt::Pad>;
+  using AsIndex = As<Fmt::Index>;
+  using AsCursor = As<Fmt::Cursor>;
+  using AsField = As<Fmt::Field>;
+  using AsAccel = As<Fmt::Accel>;
+  using AsLabel = As<Fmt::Label>;
+  using AsEditMode = As<Fmt::EditMode>;
+  using AsValue = As<Fmt::Value>;
+  using AsUnit = As<Fmt::Unit>;
+
+  //hold an Id of type T
+  template <typename T>
+  struct StaticIdOf
+  {
+    template <T id>
+    struct Id
+    {
+      template <typename O = Empty<Nil>>
+      struct Part:O{
+        bool chkId(T n) const { return id == n; }
+      };
+    };
+  };
+
+  //Idx type Id
+  template<Idx id>
+  using Id = StaticIdOf<Idx>::Id<id>;
+
+  //empty dumb part
+  struct Zen {template <typename O>struct Part : O{};};
+
+  //holds runtiume construct const char* (C string)
+  struct Text
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : O
+    {
+      // named("Text")
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      const char *text;
+      template <typename... OO>
+      constexpr Part(const char* o, OO... oo) : text(o), Base(oo...) {}
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &o, int n=0, bool sel=false) {
+        // _trace(clog<<" {Text::printTo} "<<text<<endl);
+        o.print(text);
+      }
+    };
+  };
+
+  //use static `const char*`
+  template <const ConstText *text>
+  struct StaticText
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : O
+    {
+// named("StaticText")
+#if defined(RS_DEBUG)
+      static constexpr const char *name = "StaticText";
+      static constexpr const char *(named)() { return name; }
+      // static void names() {
+      //   MDO::print(name);
+      //   MDO::print("(\"");
+      //   MDO::print(text[0]);
+      //   MDO::print("\")");
+      //   MDO::print("/");
+      //   Base::names();
+      // }
+#endif
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      template <typename Nav, typename Out, bool delegate = true>
+      static void printTo(Nav &nav, Out &out, int n = 0, bool sel = false) {
+        out.print(text[0]);
+        if (delegate)
+          Base::printTo(nav, out, n, sel);
+      }
+    };
+  };
+
+  template <const Menu::ConstText *text>
+  struct SCText {
+    template<typename O>
+    struct Part:Text::template Part<O> {
+      using Base=typename Text::template Part<O>;
+      using This=Part<O>;
+      template <typename... OO>
+      Part(OO... oo):Base(text[0],oo...) {}
+    };
+  };
+
+  //this events will reequires an event emiter...
+  // we cab have simpler handlers for keys, not the same thing but simpler (no emiter required)
+  // using Events=uint8_t;
+  // enum class Event:Events {
+  //   None=0<<0,
+  //   Enter=1<<0,
+  //   Esc=1<<1,
+  //   Focus=1<<2,
+  //   Blur=1<<3,
+  //   Update=1<<4,
+  //   Any=0xFF
+  // };
+
+  // template<Events handled,bool (*fn)(Events)>
+  // struct On {
+  //   bool event(Events e) {return fn(e);}
+  // };
+
+  template <Cmd cmdCode,ActionFn fn,bool io=true>
+  struct OnCmd {
+    template <typename O>
+    struct Part : O {
+      using Base = O;
+      using This = Part<O>;
+      template<typename Nav,Cmd c>
+      bool cmd(Nav& nav,int code=0) {
+        if(io&&(c==cmdCode)) fn();
+        auto r=Base::template cmd<Nav,c>(nav,code);
+        if((!io)&&(c==cmdCode)) fn();
+        return r;
+      }
+    };
+  };
+
+    //Associate an action
+  //triggered at `enter` call
+  template <ActionFn fn>
+  struct StaticAction {
+    template <typename O>
+    struct Part : O {
+      // named("Action");
+      using Base = O;
+      using This = Part<O>;
+      using Base::Base;
+      template <typename Nav>
+      inline bool enter(Nav& nav) {
+        // _trace(clog<<"Action::enter"<<endl);
+        Base::enter(nav);return action();}
+      inline bool action() {//note: can not be static because of `enabled()`, its a runtime property... move it to enter
+        return Base::obj().enabled() ? fn() : !has<Style::IsMenu>(Base::styles());
+      }
+    };
+  };
+
+  struct Action {
+    template <typename O>
+    struct Part : O {
+      // named("Action");
+      using Base = O;
+      using This = Part<O>;
+      using Base::Base;
+      ActionFn fn;
+      Part(ActionFn action):fn(action) {}
+      template <typename Nav>
+      inline bool enter(Nav& nav) {Base::enter(nav);return fn();}
+      inline bool action() {return Base::obj().enabled() ? fn() : !has<Style::IsMenu>(Base::styles());}
+    };
+  };
+
+  template <ActionFn fn>
+  struct SCAction {
+    template <typename O>
+    struct Part : Action::Part<O> {
+      using Base = Action::Part<O>;
+      using This = Part<O>;
+      using Base::Base;
+      Part():Base(fn) {}
+    };
+  };
+
+  //enable/diable runtime setting
+  template <bool e = true>
+  struct EnDis
+  {
+    template <typename I>
+    struct Part : public I
+    {
+    public:
+      using I::I;
+      inline bool enabled() const { return isEnabled; }
+      inline void enable(bool b) { isEnabled = b; }
+
+    protected:
+      bool isEnabled = e;
+    };
+  };
+
+  //disable commands when condition not met
+  //use this to disable commands when device is off
+  template<typename F,F& f>
+  struct When {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      template<typename Nav,Cmd c>
+      bool cmd(Nav& nav,int code=0) {
+        // _trace(clog<<"When::cmd "<<f()<<endl);
+        return f()?Base::template cmd<Nav,c>(nav,code):false;
+      }
+      template<typename Nav> bool up(Nav& nav) {
+        return f()?Base::template up<Nav>(nav):false;
+      }
+      template<typename Nav> bool down(Nav& nav) {
+        return f()?Base::template down<Nav>(nav):false;
+      }
+      template<typename Nav> bool enter(Nav& nav) {
+        return f()?Base::template enter<Nav>(nav):false;
+      }
+      template<typename Nav> bool esc(Nav& nav) {
+        return f()?Base::template esc<Nav>(nav):false;
+      }
+      template<typename Nav> bool left(Nav& nav) {
+        return f()?Base::template left<Nav>(nav):false;
+      }
+      template<typename Nav> bool right(Nav& nav) {
+        return f()?Base::right(nav):false;
+      }
+      template<typename Nav> bool key(Nav& nav,Key k) {
+        return f()?Base::template key<Nav>(nav,k):false;
+      }
+    };
+  };
+
+  template<ActionFn f>
+  struct OnUpdate {
+    template<typename O>
+    struct Part:O {
+      using Base=O;
+      using This=Part<O>;
+      using Base::Base;
+      using V=typename Base::ValueType;
+      void set(V o) {
+        // _trace(clog<<"OnUpdate::set"<<endl);
+        Base::set(o);
+        f();
+      }
+    };    
+  };
+
+  template<template<typename> class O>
+  using LabelOf=Chain<AsLabel::Part,O>;
+
+  //utility, use constText as static label
+  template <const ConstText *text>
+  using StaticLabel = LabelOf<StaticText<text>::template Part>;
+
+  //utility, use constText as label
+  using Label = LabelOf<Text::template Part>;
+
+  template <const ConstText *text>
+  struct SCLabel {
+    template<typename O>
+    struct Part:Label::Part<O> {
+      using Base = typename Label::Part<O>;
+      template<typename... OO> Part(OO... oo):Base(text[0],oo...) {}
+    };
+  };
+
+  #ifdef ARDUINO
+    //use static constructed `const char*`
+    // template <const PROGMEM char *text>
+    // struct FlashText {
+    //   template <typename O = Empty<Nil>>
+    //   struct Part : O {
+    //     using Base = O;
+    //     using This = Part<Base>;
+    //     using Base::Base;
+    //     template <typename Nav, typename Out, bool delegate = true>
+    //     void printTo(Nav &nav, Out &out, int n = 0, bool sel = false) {
+    //       out.print(text[0]);
+    //       if (delegate)
+    //         Base::printTo(nav, out, n, sel);
+    //     }
+    //   };
+    // };
+
+    // template <const PROGMEM char *text>
+    // using FlashLabel = Chain<AsLabel::Part, FlashText<text>::template Part>;
+
+  #endif
+}; //Menu namespace
\ No newline at end of file
diff --git a/src/menu/sys/fields.h b/src/menu/sys/fields.h
new file mode 100644
index 00000000..f9d20571
--- /dev/null
+++ b/src/menu/sys/fields.h
@@ -0,0 +1,783 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "../item.h"
+#ifndef ARDUINO
+#include <cstring>
+#endif
+namespace Menu
+{
+
+  //Value, for enumeration
+  template <typename T, T val, bool isDef = false>
+  struct Value
+  {
+    template <typename O>
+    struct Part : O
+    {
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      using ValueType = T;
+      inline static constexpr T value() { return val; }
+      inline static constexpr T get() { return val; }
+      static bool valueIs(T &v) { return val == v; }
+      static constexpr bool isDefault() { return isDef; }
+    };
+  };
+
+  //enumerated field
+  //as a regular field but holding a list of possible values
+  template <typename V>
+  struct EnumField
+  {
+    template <typename O>
+    struct Part : O
+    {
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      using Values = V; //Value type
+      Values values;    //values enumeration
+      //set target value from navigation index
+      void enumSet(Idx i)
+      {
+        // _trace(clog<<"EnumField::enumSet idx:"<<i<<endl;clog.flush());
+        auto sel = PathRef(1, &i);
+        using Target = typename Base::ValueType;
+        Target selVal = sel.template walk<Values, GetValue>(values);
+        Base::set(selVal);
+      }
+      template <typename Nav>
+      void enumSet(Nav &nav)
+      {
+        // _trace(clog<<"EnumField::enumSet<Nav>"<<nav.at()[0]<<endl);
+        enumSet(nav.at()[0]);
+      }
+    };
+  };
+
+  //enumeration, opens enumerated values lists as sub-menu
+  template <typename V>
+  struct Choose
+  {
+    template <typename O>
+    struct Part : EnumField<V>::template Part<O>
+    {
+      using Base = typename EnumField<V>::template Part<O>;
+      using This = Part<Base>;
+      using Base::Base;
+      using Values = V;
+      using ValueType = V;
+      template <typename Nav>
+      bool enter(Nav &nav)
+      {
+        nav.open(Base::values.template find<ValueIs, 0>(Base::get()));
+        nav.focus(true);
+        return true;
+      }
+      template <typename Nav, Cmd c>
+      bool cmd(Nav &nav, int code = 0)
+      {
+        if (c == Cmd::Enter)
+        {
+          // _trace(clog<<"Choose::Cmd<Nav,Enter>"<<endl;clog.flush(););
+          Base::enumSet(nav);
+          nav.focus(false);
+          nav.close();
+          return false;
+        }
+        // auto r=
+        Base::values.template cmd<Nav, c>(nav, code);
+        return true;
+      }
+      template <typename Nav, typename Out>
+      void onPrintMenuTo(Nav &nav, Out &out,Idx level, int n) { Base::values.template onPrintMenuTo<Nav, Out>(nav, out, level, n); }
+      template <typename Nav, typename Out>
+      void onPrintTitleTo(Nav &nav, Out &out) { Base::values.template onPrintTitleTo<Nav, Out>(nav, out); }
+      template <typename Nav, typename Out>
+      void onPrintBodyTo(Nav &nav, Out &out,Idx level, Idx selIdx, Idx n) { Base::values.template onPrintBodyTo<Nav, Out>(nav, out,level, n); }
+      // template<typename Nav,typename Out> void onPrintItemTo(Nav& nav,Out& out,Idx level {O::obj().printTo(nav,out);}
+      // void setDefault() {
+      //   Idx selPath[1]{0};
+      //   if(selPath[0]>=Base::values.len()) setDefault();
+      // }
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &o, int n = 0, bool sel = false)
+      {
+        // _trace(clog<<"Choose::printTo"<<endl;clog.flush());
+        //TODO:: use & instead of array!
+        Idx selPath[1]{0};
+        selPath[0] = Base::values.template find<ValueIs, 0>(Base::get());
+        // _trace(clog
+        //   <<"selPath[0]:"<<selPath[0]
+        //   <<">= sz:"<<Base::values.len()
+        //   <<"? "<<(selPath[0]>=Base::values.len()?"yes":"no")
+        //   <<endl;clog.flush();
+        // );
+        if (selPath[0] >= Base::values.len())
+        {
+          // _trace(clog<<"out of range data"<<endl);
+          selPath[0] = Base::values.template find<IsDefault, 0>();
+          // _trace(clog<<"found default idx:"<<selPath[0]<<endl);
+          if (selPath[0] >= Base::values.len())
+            return;
+          // _trace(clog<<"setting enum"<<endl);
+          Base::enumSet(selPath[0]);
+        }
+        PathRef(1, selPath).template walk<decltype(Base::values), PrintTo, Nav &, Out &>(Base::values, nav, o, n, sel);
+        // if(delegate) Base::printTo(nav,o,n,sel);
+      }
+      constexpr Idx sz() { return Base::values.sz(); }
+      constexpr Idx _sz() { return Base::values._sz(); }
+    };
+  };
+
+  //enumeration, enters field edit and navigates list of values
+  template <typename V>
+  struct Select
+  {
+    template <typename O>
+    struct Part : Chain<ParentDraw::template Part, Choose<V>::template Part>::template To<O>
+    {
+      using Base = typename Chain<ParentDraw::template Part, Choose<V>::template Part>::template To<O>;
+      using This = Part<Base>;
+      using Base::Base;
+      template <typename Nav, Cmd c>
+      bool cmd(Nav &nav, int code = 0)
+      {
+        bool r = Base::template cmd<Nav, c>(nav, code);
+        if (c == Cmd::Up || c == Cmd::Down)
+          Base::enumSet(nav);
+        return r;
+      }
+    };
+  };
+
+  //enumeration, change value on enter => wrap nav.
+  template <typename V, char cursor = ':'>
+  struct Toggle
+  {
+    template <typename O>
+    struct Part : Chain<WrapNav::Part, ParentDraw::template Part, Choose<V>::template Part>::template To<O>
+    {
+      using Base = typename Chain<WrapNav::Part, ParentDraw::template Part, Choose<V>::template Part>::template To<O>;
+      using This = Part<Base>;
+      using Base::Base;
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &o, int n = 0, bool sel = false)
+      {
+        // _trace(clog<<"Toggle::printTo"<<endl;clog.flush());
+        o.print(cursor);
+        Base::printTo(nav, o, n, sel);
+        // if(delegate) Base::printTo(nav,o,n,sel);
+      }
+      template <typename Nav>
+      bool enter(Nav &nav)
+      {
+        Idx selIdx = Base::values.template find<ValueIs, 0>(Base::get());
+        nav.open(selIdx);
+        nav.up();
+        Base::enumSet(nav);
+        nav.close();
+        return false;
+      }
+    };
+  };
+
+  // static binded to a reference
+  template <typename T, T &target, T def>
+  struct FieldRef
+  {
+    template <typename O>
+    struct Part : O
+    {
+      using ValueType = T;
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      T reflex;
+      template <typename... OO>
+      Part(OO... oo) : reflex(def), Base(oo...) {}
+      void setDefault() { reflex = target = def; }
+      bool changed() { return reflex != target; }
+      void changed(bool o) {
+        if (o)
+          reflex ^= 1;
+        else
+          reflex = target;
+      }
+      void set(T o) {
+        target = o;
+        Base::obj().action();
+      }
+      T get() const {return target;}
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &o, int n = 0, bool sel = false)
+      {
+        // _trace(clog<<"FieldRef::printTo"<<endl;clog.flush());
+        o.print(get());
+        if (delegate)
+          Base::printTo(nav, o, n, sel);
+      }
+    };
+  };
+
+  //functional field, no data or reference stored, other than the change checking data ofcoz
+  template<typename T,T(&fget)(),void(&fset)(T),T def>
+  struct FuncField {
+    template<typename O>
+    struct Part:O {
+      using ValueType = T;
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      T reflex;
+      template <typename... OO>
+      Part(OO... oo) : reflex(def), Base(oo...) {}
+      void setDefault() { reflex = def; fset(def);}
+      bool changed() { return reflex != fget(); }
+      void changed(bool o) {
+        if (o)
+          reflex ^= 1;
+        else
+          reflex = fget();
+      }
+      void set(T o) {
+        reflex = o;
+        fset(o);
+        Base::obj().action();
+      }
+      inline T get() const {return fget();}
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &o, int n = 0, bool sel = false)
+      {
+        o.print(get());
+        if (delegate)
+          Base::printTo(nav, o, n, sel);
+      }
+    };
+  };
+
+  // template<typename T,T(&fget)(),T(&fset)(T),T def>
+  // struct FuncField:FuncFieldBase<T,fget,fset,def> {};
+  // template<typename T,T(&fget)(),T def>
+  // struct FuncField<T,fget,fget,def>:FuncFieldBase<T,fget,fget,def> {};
+
+  template <typename T, T def>
+  struct FieldValBase
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : O
+    {
+      using ValueType = T;
+      using Base = O;
+      using This = Part<O>;
+      using Base::Base;
+      Part(const This &) = delete;
+      Part &operator=(const This &) = delete;
+      T value;
+      T dirty = true;
+      template <typename... OO>
+      Part(OO... oo) : value(def), Base(oo...) {}
+      void setDefault() {
+        dirty |= value == def;
+        value = def;
+      }
+      bool changed() { return dirty; }
+      void changed(bool o) { dirty = o; }
+      void set(T o) {
+        value = o;
+        Base::obj().action();
+      }
+      T get() const { return value; }
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &o, int n, bool sel) {
+        o.print(get());
+        if (delegate)
+          Base::printTo(nav, o, n, sel);
+      }
+    };
+  };
+
+  //storing data value
+  template <typename T, T def>
+  struct FieldVal {
+    template <typename O = Empty<Nil>>
+    struct Part : FieldValBase<T,def>::template Part<O> {
+      using ValueType = T;
+      using Base = typename FieldValBase<T,def>::template Part<O>;
+      using This = Part<O>;
+      using Base::Base;
+    };
+  };
+
+  template <uint8_t def>
+  struct FieldVal<uint8_t,def> {
+    template <typename O = Empty<Nil>>
+    struct Part : FieldValBase<uint8_t,def>::template Part<O> {
+      using ValueType = uint8_t;
+      using Base = typename FieldValBase<uint8_t,def>::template Part<O>;
+      using This = Part<O>;
+      using Base::Base;
+      void changed(bool o) {}
+      template <typename Nav, typename Out, bool delegate = true>
+      void printTo(Nav &nav, Out &o, int n, bool sel) {
+        o.print((int)Base::get());
+        if (delegate)
+          Base::Base::printTo(nav, o, n, sel);
+      }
+    };
+  };
+
+  // template<typename T,T def,uint16_t id=0>
+  // struct StaticFieldVal {
+  //   template<typename O=Empty<Nil>>
+  //   struct Part:O {
+  //     using ValueType=T;
+  //     using Base=O;
+  //     using This=Part<Base>;
+  //     using Base::Base;
+  //     static T value;
+  //     static T dirty;
+  //     // template<typename... OO>
+  //     // Part(OO... oo):value(def),Base(oo...) {}
+  //     static bool changed() {return dirty;}
+  //     static void changed(bool o) {dirty=o;}
+  //     static void set(T o) {
+  //       dirty=o!=value;
+  //       value=o;
+  //       // Base::obj().action();//static fields can not have associated action
+  //       //unless we make a Static action... and eventually a static enable/disable
+  //     }
+  //     static T get() {return value;}
+  //     template<typename Nav,typename Out,bool delegate=true>
+  //     void printTo(Nav& nav,Out& o,int n,bool sel) {
+  //       o.print(get());
+  //       if(delegate)Base::printTo(nav,o,n,sel);
+  //     }
+  //   };
+  // };
+
+
+  //Static range (low and high values)
+  template <typename T, T lowVal, T highVal>
+  struct StaticRange
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : O
+    {
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      static constexpr T low() { return lowVal; }
+      static constexpr T high() { return highVal; }
+      static void constrainField() { Base::obj().set(constrain(Base::obj().get(), low(), high())); }
+    };
+  };
+
+  //numeric range validation and change deltas (step and tune)
+  template <typename T, T lowVal, T highVal, T stepSz, T tuneSz, T def = 0>
+  struct StaticSTRange
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : StaticRange<T, lowVal, highVal>::template Part<O>
+    {
+      using Base = typename StaticRange<T, lowVal, highVal>::template Part<O>;
+      using This = Part<Base>;
+      using Base::Base;
+      static constexpr T tune() { return tuneSz; }
+      static constexpr T step() { return stepSz; }
+    };
+  };
+
+  //numeric range
+  template<typename T>
+  struct Range {
+    template<typename O>
+    struct Part:O {
+      using This=Part<O>;
+      using Base=O;
+      using Base::Base;
+      T lowVal,highVal;
+      template<typename... OO>
+      Part(T low,T high,OO... oo):lowVal(low),highVal(high),Base(oo...) {}
+      constexpr T low() const { return lowVal; }
+      constexpr T high() const { return highVal; }
+      void constrainField() { Base::obj().set(constrain(Base::obj().get(), low(), high())); }
+    };
+  };
+
+  //numeric range with step/tune change values
+  template<typename T>
+  struct STRange {
+    template<typename O>
+    struct Part:Range<T>::template Part<O> {
+      using This=Part<O>;
+      using Base=typename Range<T>::template Part<O>;
+      using Base::Base;
+      T stepSz,tuneSz;
+      template<typename... OO>
+      Part(T low,T high,T step, T tune,T def,OO... oo):stepSz(step),tuneSz(tune),Base(low,high,oo...) {}
+      constexpr T tune() const { return tuneSz; }
+      constexpr T step() const { return stepSz; }
+    };
+  };
+
+  //TODO separate default values from this structures
+  template <typename T, T lowVal, T highVal, T stepSz, T tuneSz, T def = 0>
+  struct SCSTRange {
+    template<typename O>
+    struct Part:STRange<T>::template Part<O> {
+      using This=Part<O>;
+      using Base=typename STRange<T>::template Part<O>;
+      template<typename... OO>
+      Part(OO... oo):Base(lowVal,highVal,stepSz,tuneSz,def,oo...) {}
+    };
+  };
+
+  //set nav status for field edit/tune
+  struct EditCtrl
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : O
+    {
+      using Base = O;
+      using This = Part<Base>;
+      using Base::Base;
+      template <typename Nav>
+      bool enter(Nav &nav)
+      {
+        // _trace(clog << "EditCtrl::enter" << endl);
+        if (nav.focus())
+        {
+          nav.tune(nav.tune() ^ Base::tune());
+          nav.focus(nav.tune());
+        }
+        else
+          nav.focus(true);
+        // return
+        // Base::enter(nav);
+        return true;
+      }
+      template <typename Nav>
+      bool esc(Nav &nav)
+      {
+        // _trace(clog<<"esc!"<<endl);
+        nav.tune(0);
+        nav.focus(0);
+        // return
+        Base::enter(nav);
+        return true; //irrelevant
+      }
+    };
+  };
+
+  //when ranged or enumerated values can wrap
+  struct Wrap
+  {
+    template <typename O>
+    struct Part : O
+    {
+      inline static constexpr bool canWrap() { return true; }
+    };
+  };
+
+  //validate numeric field value by range info
+  struct RangeValid
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : EditCtrl::Part<O>
+    {
+      using Base = typename EditCtrl::Part<O>;
+      using This = Part<Base>;
+      using Base::Base;
+      using Type = typename Base::ValueType;
+      template <typename Nav>
+      void stepit(Nav &nav, int dir)
+      {
+        // dir*=options->invertFieldKeys?-1:1;
+        Type thisstep = nav.tune() ? Base::tune() : Base::step();
+        // Base::obj().changed(true);
+        //by default they are inverted.. now buttons and joystick have to flip them
+        if (dir > 0) {
+          if ((Base::high() - Base::get()) < thisstep)
+            Base::set(Base::canWrap() ? Base::low() : Base::high());
+          else
+            Base::set(Base::get()+thisstep);
+        } else {
+          if ((Base::get() - Base::low()) < thisstep)
+            Base::set(Base::canWrap() ? Base::high() : Base::low());
+          else
+            Base::set(Base::get()-thisstep);
+        }
+      }
+      template <typename Nav>
+      bool up(Nav &nav)
+      {
+        if (nav.focus()) {
+          // Base::set(Base::get() + (nav.tune() ? Base::tune() : Base::step()));
+          stepit(nav,1);
+          return true;
+        }
+        return false;
+      }
+      template <typename Nav>
+      bool down(Nav &nav)
+      {
+        if (nav.focus())
+        {
+          Base::set(Base::get() - (nav.tune() ? Base::tune() : Base::step()));
+          // stepit<Nav,Type>(nav,-1);
+          return true;
+        }
+        return false;
+      }
+    };
+  };
+
+  //change numeric value with acceleration
+  template <int relaxTimeout = 300, int rate = 1>
+  struct ValueAccel
+  {
+    template <typename O>
+    struct Part : O
+    {
+      using Base = O;
+      using This = Part<O>;
+      using Type = typename Base::ValueType;
+      static constexpr Type tune() { return 0; }
+      // Type value=0;
+      int accel = 0;
+      TinyTimeUtils::template TickCnt<relaxTimeout> relax;
+      using Base::get;
+      using Base::high;
+      using Base::low;
+      using Base::set;
+      template <typename Nav>
+      bool up(Nav &nav)
+      {
+        // _trace(clog<<"Accel up: "<<accel<<endl);
+        if (accel >= 0)
+          accel += rate;
+        else
+          accel /= -2;
+        if (high() - get() < accel)
+          set(high());
+        else
+        {
+          set(get() + accel);
+          relax.reset();
+        }
+        return Base::up(nav);
+      }
+      template <typename Nav>
+      bool down(Nav &nav)
+      {
+        // _trace(clog<<"Accel down: "<<accel<<endl);
+        if (accel <= 0)
+          accel -= rate;
+        else
+          accel /= -2;
+        if (get() - low() < -accel)
+          set(low());
+        else
+        {
+          set(get() + accel);
+          relax.reset();
+        }
+        return Base::down(nav);
+      }
+      template <typename Dev>
+      inline void poll(Dev &dev)
+      {
+        // _trace(if(accel) clog<<"ValueAccel::poll() cnt:"<<((uint16_t)relax)<<endl);
+        if (relax)
+        {
+          accel = accel >> relax;
+          relax.reset();
+        }
+      }
+    };
+  };
+
+  //static bind to numeric reference
+  template <typename T, T &target, T def = 0>
+  struct NumRef
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : Chain<RangeValid::Part, FieldRef<T, target, def>::template Part>::template To<O>
+    {
+      using Base = typename Chain<RangeValid::Part, FieldRef<T, target, def>::template Part>::template To<O>;
+      using This = Part<Base>;
+      using Base::Base;
+      constexpr static bool valueIs(T &v) { return target == v; }
+    };
+  };
+
+  //storing numeric value with validation range
+  template <typename T, T def = 0>
+  struct NumVal
+  {
+    template <typename O = Empty<Nil>>
+    struct Part : Chain<RangeValid::Part, FieldVal<T, def>::template Part>::template To<O>
+    {
+      using Base = typename Chain<RangeValid::Part, FieldVal<T, def>::template Part>::template To<O>;
+      using This = Part<Base>;
+      using Base::Base;
+    };
+  };
+
+  //edit a text buffer
+  template <char *buffer, Idx buffSz, ConstText masks[], char def = ' '>
+  struct TextEditBase
+  {
+    template <typename O = Empty<>>
+    struct Part : IsMenu::Part<ParentDraw::Part<O>>
+    {
+      using Base = IsMenu::Part<ParentDraw::Part<O>>;
+      using This = Part<O>;
+      using Base::Base;
+      static constexpr Idx sz() { return buffSz - 1; }
+      template <typename Nav>
+      static bool enter(Nav &nav) {
+        // _trace(mdo<<"TextEditBase::enter\n\r");
+        nav.open();
+        nav.focus(true);
+        return false;
+      }
+      static ConstText validator(int i) {
+        return masks[i % (sizeof(masks) / sizeof(masks[0]))];
+      }
+      template <typename Nav, Cmd c>
+      static bool cmd(Nav &nav, int code = 0) {
+        switch (c)
+        {
+        //from AM4
+        case Cmd::Enter:
+          if (nav.tune() && !nav.edited())
+          {
+            nav.focus(false);
+            nav.tune(false);
+            nav.close();
+            return false;
+          }
+          else
+          {
+            nav.tune(!nav.tune());
+            if (nav.tune())
+              nav.edited(false);
+            return false;
+          }
+        case Cmd::Esc:
+          nav.tune(false);
+          nav.focus(false);
+          nav.close();
+          return false;
+        case Cmd::Up:
+          if (nav.tune())
+          {
+            const char *v = validator(nav.pos());
+            const char *at = strchr(v, buffer[nav.pos()]);
+            Idx pos = at ? at - v + 1 : 1;
+            if (pos >= (Idx)strlen(v))
+              pos = 0;
+            buffer[nav.pos()] = v[pos];
+            nav.edited(true);
+            return true;
+          }
+          break;
+        case Cmd::Down:
+          if (nav.tune())
+          {
+            const char *v = validator(nav.pos());
+            const char *at = strchr(v, buffer[nav.pos()]);
+            int pos = at ? at - v - 1 : 0;
+            if (pos < 0)
+              pos = strlen(v) - 1;
+            buffer[nav.pos()] = v[pos];
+            nav.edited(true);
+            return true;
+          }
+          break;
+        default:
+          break;
+        }
+        return nav.template doNav<c>(sz(), Base::styles()); //generic menu nav
+      }
+      template <typename Nav, typename Out, bool delegate = true>
+      static void printTo(Nav &nav, Out &out, int n = 0, bool sel = false)
+      {
+        // _trace(clog<<"TextEditBase::printTo"<<endl;clog.flush());
+        if (sel /*&&editing*/)
+        { //if we are here then we are editing
+          if (nav.pos())
+            out.write(buffer, nav.pos());
+          out.template fmtStart<Fmt::EditCursor>(nav.focus(), nav.tune());
+          out.print((char)buffer[nav.pos()]);
+          out.template fmtStop<Fmt::EditCursor>(nav.focus(), nav.tune());
+          if (nav.pos() < sz() - 1)
+            out.print(buffer + nav.pos() + 1);
+        }
+        else
+          out.print(buffer);
+        if (delegate)
+          Base::printTo(nav, out, n, sel);
+      }
+      template <typename Nav, typename Out>
+      static void onPrintMenuTo(Nav &nav, Out &out,Idx level, int) {}
+      template <typename Nav, typename Out>
+      static void onPrintTitleTo(Nav &nav, Out &out) {}
+      template <typename Nav, typename Out>
+      static void onPrintBodyTo(Nav &nav, Out &out,Idx level, Idx selIdx, Idx n) {}
+      // template <typename Nav, typename Out>
+      // void onPrintItemTo(Nav &nav, Out &out,Idx level, int n, bool sel)
+      // {
+      //   O::obj().template printTo<Nav, Out>(nav, out, n, sel);
+      // }
+    };
+  };
+
+  template <char *buffer, Idx len, ConstText mask[], char def = ' '>
+  using TextEdit = Chain<
+      AsEditMode::Part,
+      AsValue::Part,
+      TextEditBase<buffer, len, mask, def>::template Part>;
+
+  template<typename T,T def=0>
+  struct NumField {
+    template<typename O>
+    using Part=typename Chain<
+      Menu::AsEditMode::Part,
+      Menu::AsValue::Part,//format as value
+      Menu::EditCtrl::Part,//editable
+      Menu::RangeValid::Part,//use step/tune to change field value
+      Menu::FieldVal<T,def>::template Part
+    >::template To<O>;
+  };
+
+  template<typename T,T& ref,T def=0>
+  struct NumFieldRef {
+    template<typename O>
+    using Part=typename Chain<
+      Menu::AsEditMode::Part,
+      Menu::AsValue::Part,//format as value
+      Menu::EditCtrl::Part,//editable
+      Menu::RangeValid::Part,//use step/tune to change field value
+      Menu::FieldRef<T,ref,def>::template Part
+    >::template To<O>;
+  };
+
+  template<typename T,T(&get)(),void(&set)(T),T def>
+  struct NumFuncField {
+    template<typename O>
+    using Part=typename Chain<
+      Menu::AsEditMode::Part,
+      Menu::AsValue::Part,//format as value
+      Menu::EditCtrl::Part,//editable
+      Menu::RangeValid::Part,//use step/tune to change field value
+      Menu::FuncField<T,get,set,def>::template Part
+    >::template To<O>;
+  };
+
+}; //Menu namespace
\ No newline at end of file
diff --git a/src/menu/sys/menuDebug.h b/src/menu/sys/menuDebug.h
new file mode 100644
index 00000000..961edd06
--- /dev/null
+++ b/src/menu/sys/menuDebug.h
@@ -0,0 +1,41 @@
+/* -*- C++ -*- */
+#pragma once
+
+#include "menu/sys/kernel/debug.h"
+#include "menu/sys/kernel/base.h"
+
+namespace Menu {
+  #if defined(RS_DEBUG)&&!defined(RELEASE)
+    #ifdef ARDUINO
+      struct DebugOut {
+        template<typename Data>
+        static void print(Data o) {Serial.print(o);}
+        static void nl() {Serial.println();}
+        template<Fmt,bool> static void fmt(int n=0,bool sel=false) {}
+        template<Fmt tag> void fmtStart(int n=0,bool sel=false) {fmt<tag,true>(n,sel);}
+        template<Fmt tag> void fmtStop(int n=0,bool sel=false) {fmt<tag,false>(n,sel);}
+      };
+    #else
+      #include <iostream>
+      struct DebugOut {
+        template<typename Data>
+        static void print(Data o) {std::cout<<o;}
+        static void nl() {std::cout<<std::endl;}
+        template<Fmt,bool> static void fmt(int n=0,bool sel=false) {}
+        template<Fmt tag> void fmtStart(int n=0,bool sel=false) {fmt<tag,true>(n,sel);}
+        template<Fmt tag> void fmtStop(int n=0,bool sel=false) {fmt<tag,false>(n,sel);}
+      };
+    #endif
+    // template<typename Out,typename Data>
+    // DebugOut& operator<<(Out& out,Data data) {out.print(data);return out;}
+    using MDO=DebugOut;
+
+    extern MDO mdo;
+    inline void ptrIs(){}
+    template<typename O,typename... OO> 
+      inline void ptrIs(const O& o,OO... oo)
+      {mdo<<&o<<" ";ptrIs(oo...);}
+
+  #endif
+
+};
\ No newline at end of file
diff --git a/src/menu/sys/staticMenu.h b/src/menu/sys/staticMenu.h
new file mode 100644
index 00000000..ffb40269
--- /dev/null
+++ b/src/menu/sys/staticMenu.h
@@ -0,0 +1,124 @@
+/* -*- C++ -*- */
+#pragma once
+/**
+* @author Rui Azevedo
+* @brief static (type defined/compile time) menu
+* no structure data will be stored, all beavior is implemented by code instead of data
+* making this structure as thin as user encoded menus (pure functional, no data)
+* just as hand coded menus for small devices (low ram)
+*/
+
+#include "../parts/src/parts.h"
+using namespace Parts;
+
+#include "../item.h"
+
+namespace Menu {
+  template<typename O,typename... OO>
+  struct StaticList:Node<O,StaticList<OO...>> {
+    // named("StaticList<O,OO...>");
+    using Tail=StaticList<OO...>;
+    using Base=Node<O,Tail>;
+    using This=StaticList<O,OO...>;
+    using Base::Base;
+    // template<typename... Args>
+    // StaticList(Args... args):Base(args...) {}
+    // template<typename... Args>
+    // StaticList(Args... args):Base(args...,Base::template build<Tail,Args...>(args...)) {}
+    template<typename Nav,typename Out>
+    void onPrintBodyTo(Nav& nav,Out& out,Idx level,Idx selIdx,Idx n)  {
+      out.template printItem<Nav,This>(nav,*this,level,n,n==selIdx);
+      Base::tail().template onPrintBodyTo<Nav,Out>(nav,out,level,selIdx,n+1);
+    }
+    static constexpr Idx len() {return Base::_sz();}
+    void begin() {
+      Base::head().begin();
+      Base::tail().begin();
+    }
+};
+
+  template<typename O>
+  struct StaticList<O>:Node<O,Nil> {
+    // named("StaticList<O>");
+    using Base=Node<O,Nil>;
+    using This=StaticList<O>;
+    using Base::Base;
+    template<typename... Args>
+    StaticList(Args... args):Base(args...) {}
+    template<typename Nav,typename Out>
+    void onPrintMenuTo(Nav& nav,Out& out,Idx level,Idx selIdx) {out.printMenu(nav,*this,level+1,selIdx);}
+    template<typename Nav,typename Out>
+    void onPrintBodyTo(Nav& nav,Out& out,Idx level,Idx selIdx,Idx n) {out.printItem(nav,*this,level,n,selIdx==n);}
+    static constexpr Idx len() {return Base::_sz();}
+  };
+
+  template<typename... OO>
+  struct Format:StaticList<OO...> {};
+
+  template<typename O,typename... OO>
+  using StaticMenuBody=StaticList<O,OO...>;
+
+  template<typename Title,typename Body>
+  struct StaticMenu:IsMenu::Part<Body> {
+    Title title;
+    // named("StaticMenu<Title,Body...>");
+    using Base=typename IsMenu::Part<Body>;
+    using This=StaticMenu<Title,Body>;
+    using Base::Base;
+    // template<typename... Args>
+    // StaticMenu(Args... args):Title(args...),Base(Title::template build<Base,Args...>(args...)) {}
+    template<typename Nav,typename Out,bool delegate=true>
+    void printTo(Nav& nav,Out& out,int n=0,bool sel=false) {
+      title.template printTo<Nav,Out>(nav,out,n,sel);
+    }
+    template<typename Nav,typename Out>
+    void onPrintMenuTo(Nav& nav,Out& out,Idx level,Idx selIdx) 
+      {out.template printMenu<Nav,This>(nav,*this,level+1,selIdx);}
+    template<typename Nav,typename Out>
+    void onPrintTitleTo(Nav& nav,Out& out) 
+      {out.printTitle(nav,title);}
+    template<typename Nav,typename Out>
+    void onPrintItemTo(Nav& nav,Out& out,Idx level,Idx n=0,bool sel=0) {
+      //TODO: allow combination of the types (mask) instead of the combination of results!
+      // so that this is possoble `(has<Style::PadDraw&&Style::ParentDraw>(Base::styles())`
+      // need to change `has` & `is` from Style to decltype(Style)? C++ should know it better...
+      if(has<Style::PadDraw>(Base::styles())&has<Style::ParentDraw>(Base::styles())) {
+        out.padOn();
+        out.template printMenu<Nav,This>(nav,*this,level+1,nav.pos());//TODO: nav pos() need to b corrected & menus need a preview print
+        out.padOff();
+      } else title.printTo(nav,out,n,sel);
+}
+
+    // #define keyWalker(f,n)
+    // template<int... path>
+    // bool f() {
+    //   using Call=typename This::template Walk<bool,typename This::n>;
+    //   return Call().template walk<This,path...>(*this);
+    // }
+
+    template<typename Nav> bool enter(Nav& nav) {return true;}
+    template<typename Nav,Cmd c> bool cmd(Nav& nav,int code=0) {
+      PathRef parent(nav.level,nav.path);
+      Style ps=parent.template walk<typename Nav::MenuType,Styles>(nav.data);
+      PathRef child(1,nav.at());
+      Style s=child.template walk<This,Styles>(*this);
+      if(has<Style::WrapNav>(ps)) s=s^Style::WrapNav;
+      //this menus can not do this kind on Base::cmd call or they will be calling childs methods...
+      //its a point in favor of non menu body inheritance
+      return /*Base::template cmd<Nav,c>(nav,code)&&*/nav.template doNav<c>(sz(),s);
+    }
+
+    // keyWalker(enter,Enter);
+    // keyWalker(esc,Esc);
+    // keyWalker(up,Up);
+    // keyWalker(down,Down);
+
+    template<typename Nav,typename Out,int... path>
+    void printMenuTo(Nav& nav,Out& out,int sel) {
+      // _trace(clog<<"StaticMenu::onPrintMenuTo"<<endl;clog.flush());
+      Path<path...>::template walk<This,PrintMenuTo,Out,int>(*this,out,sel);
+    }
+    static constexpr Idx sz() {return Base::_sz();}
+  };
+
+};
diff --git a/src/menu/sys/stdMenu.h b/src/menu/sys/stdMenu.h
new file mode 100644
index 00000000..d0f57321
--- /dev/null
+++ b/src/menu/sys/stdMenu.h
@@ -0,0 +1,109 @@
+/* -*- C++ -*- */
+#pragma once
+/**
+* @author Rui Azevedo
+* @brief std container menu
+*/
+
+#include <utility>
+#include "menu/item.h"
+
+namespace Menu {
+  template<typename Data>
+  struct StdMenu {
+    template<typename O>
+    struct Part:O {
+      Data data;
+      using Base=O;
+      using This=Part<Base>;
+      using Base::Base;
+      template<typename ...T>
+      Part(T... t):data{ std::forward<T>(t)... } {}
+      decltype(data.begin()) begin() { return data.begin(); }
+      decltype(data.end()) end() { return data.end(); }
+      decltype(data.size()) size() const { return data.size(); }
+      static constexpr Style styles() {return Style::IsMenu|Base::styles();}
+      Idx sz() const {return size();}
+      decltype(data.operator[](0)) operator[](size_t i) {return data.operator[](i); }
+
+      template<typename Target,Idx o,Idx... oo>
+      struct Walk {
+        Target& target;
+        Walk(Target& t):target(t) {}
+        template<typename API,typename... Args>
+        auto walk(Args... args) 
+          ->decltype(
+            Walk<IItem,oo...>(*target[0]).template walk<API,Args...>(args...)
+          ){
+          return Walk<IItem,oo...>(*target[o]).template walk<API,Args...>(args...);
+        }
+      };
+
+      template<typename Target,Idx o>
+      struct Walk<Target,o> {
+        Target& target;
+        Walk(Target& t):target(t) {}
+        template<typename API,typename... Args>
+        auto walk(Args... args) 
+          ->decltype(
+            API().operator()(*(target[o]),args...)
+          ){
+          return API().operator()(*(target[o]),args...);
+        }
+      };
+
+      struct RefWalk {
+        Idx pathLen;
+        const Idx* path;
+        RefWalk(Idx l,Idx* p):pathLen(l),path(p) {}
+        RefWalk(const RefWalk& p):pathLen(p.len()),path(p.path) {}
+        Idx len() const {return pathLen;}
+        Idx head() {return path[0];}
+        RefWalk tail() {return RefWalk(len()-1,(Idx*)&path[1]);}
+        template<typename Target,typename API,typename... Args>
+        auto step(Idx at,Target& target,Args... args) 
+          ->decltype(API().operator()(*target[0],args...))
+          {
+          return len()?
+            RefWalk(pathLen-1,(Idx*)&path[1])
+              .template step<decltype(*target[at]),API,Args...>(head(),*target[at],args...):
+            API().operator()(*target[at],args...);
+        }
+      };
+
+      template<typename Nav> static bool enter(Nav&) {return true;}
+
+      // using Base::cmdTo;
+      // NavRes cmdTo(Cmd c,Idx l,Idx *path) {
+      //   switch(c) {
+      //     case Cmd::Enter:return PathRef(l,path).walk<This,CmdTo<Cmd::Enter>>(*this);
+      //     case Cmd::Esc:return PathRef(l,path).walk<This,CmdTo<Cmd::Esc>>(*this);
+      //     case Cmd::Up:return PathRef(l,path).walk<This,CmdTo<Cmd::Up>>(*this);
+      //     case Cmd::Down:return PathRef(l,path).walk<This,CmdTo<Cmd::Down>>(*this);
+      //     default: assert(false);
+      //   }
+      // }
+      template<typename Nav,typename Out,int... path>
+      void printMenuTo(Nav& nav,Out& out,int sel) {
+        Walk<This,path...>(*this).template walk<PrintMenuTo,Out,int>(out,sel);
+      }
+
+      template<typename Nav,typename Out>
+      void printMenuTo(Nav& nav,Out& out,int sel) {
+        out.printMenu(nav,*this,sel);
+      }
+
+      template<typename Nav,typename Out> void onPrintTitleTo(Nav& nav,Out& out) {Base::onPrintTitleTo(nav,out);}
+      template<typename Nav,typename Out> void onPrintBodyTo(Nav& nav,Out& out,Idx level,Idx selIdx,Idx n) {
+        // Base::printTo(out);
+        int idx=0;
+        for(auto i:data) {
+          out.printItem(nav,*i,level,idx,idx==selIdx);
+          idx++;
+        }
+      }
+      template<typename Nav,typename Out> void printItemTo(Nav& nav,Out& out,Idx level) {out.printItem(Base::obj(),level);}
+    };
+  };
+
+};//Menu namespace
\ No newline at end of file
diff --git a/src/menuBase.cpp b/src/menuBase.cpp
deleted file mode 100644
index 5437fdf1..00000000
--- a/src/menuBase.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-
-#include "menuDefs.h"
-
-using namespace Menu;
-
-#ifdef MENU_DEBUG
-  bool debugFlag=false;
-  #if defined(USING_PGM)
-    const char* libMemMode="PGM";
-  #elif defined(USING_RAM)
-    const char* libMemMode="RAM";
-  #else
-    const char* libMemMode="ERROR!";
-  #endif
-#endif
-
-template<void (*A)(eventMask event, navNode& nav, prompt &item, menuIn &in)> result Menu::callCaster(eventMask event, navNode& nav, prompt &item, menuIn &in) {A(event,nav,item,in);return proceed;}
-template<void (*A)(eventMask event, navNode& nav, prompt &item)> result Menu::callCaster(eventMask event, navNode& nav, prompt &item) {A(event,nav,item);return proceed;}
-template<void (*A)(eventMask event, navNode& nav)> result Menu::callCaster(eventMask event, navNode& nav) {A(event,nav);return proceed;}
-template<void (*A)(eventMask event)> result Menu::callCaster(eventMask event) {A(event);return proceed;}
-template<void (*A)()> result Menu::callCaster() {A();return proceed;}
-
-//MEMMODE AUX PRINT
-#if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-idx_t Menu::print_P(Print& s,const char* at,idx_t len) {
-  const char* p=at;
-  uint8_t ch;
-  for(int n=0;(ch=memByte(at++))&&(len==0||n<len);n++)
-    s.write(ch);
-  return at-p-1;
-}
-#endif
-
-idx_t Menu::print_P(menuOut& s,const char* at,idx_t len) {
-  return s.printRaw(at,len);
-}
-
-const navCodesDef Menu::defaultNavCodes={
-  {noCmd,(char)0xff},
-  {escCmd,'/'},
-  {enterCmd,'*'},
-  {upCmd,'+'},
-  {downCmd,'-'},
-  {leftCmd,'-'},
-  {rightCmd,'+'},
-  {idxCmd,'?'},
-  {scrlUpCmd,0x35},
-  {scrlUpCmd,0x36}
-};
-
-config Menu::defaultOptions={'>','-',Menu::defaultNavCodes,false};
-config* Menu::options=&defaultOptions;
-
-#ifdef MENU_DEBUG
-
-  Print& Menu::operator<<(Print& o,bool b) {
-    return o<<(b?"true":"false");
-  }
-
-  Print& Menu::operator<<(Print& o,result r) {
-    switch(r) {
-      case proceed: o<<"proceed";break;
-      case quit: o<<"quit";break;
-    }
-    return o;
-  }
-
-  const char* eventName(eventMask e) {
-    switch(e) {
-      case noEvent:return "noEvent";
-      case activateEvent:return "activateEvent";
-      case enterEvent:return "enterEvent";
-      case exitEvent:return "exitEvent";
-      case returnEvent:return "returnEvent";
-      case focusEvent:return "focusEvent";
-      case blurEvent:return "blurEvent";
-      case selFocusEvent:return "selFocusEvent";
-      case selBlurEvent:return "selBlurEvent";
-      case anyEvent:return "anyEvent";
-      default: return "need to implement this print";
-    }
-  }
-
-  Print& Menu::operator<<(Print& o,eventMask e) {
-    if (e==noEvent||e==anyEvent) {o<<eventName(e); return o;}
-    bool first=true;
-    for(int n=0;n<=6;n++) {
-      eventMask t=(eventMask)(1<<n);
-      if (t&e) {
-        o<<(first?"":"|")<<eventName(t);
-        first=false;
-      }
-    }
-    return o;
-  }
-
-  Print& Menu::operator<<(Print& o,navCmds cmd) {
-    switch(cmd) {
-      case noCmd:o<<"noCmd";break;
-      case escCmd:o<<"escCmd";break;
-      case enterCmd:o<<"enterCmd";break;
-      case upCmd:o<<"upCmd";break;
-      case downCmd:o<<"downCmd";break;
-      case leftCmd:o<<"leftCmd";break;
-      case rightCmd:o<<"rightCmd";break;
-      case idxCmd:o<<"idxCmd";break;
-      case selCmd:o<<"selCmd";break;
-      default:o<<"? "<<cmd;break;
-    }
-    return o;
-  }
-
-  Print& Menu::operator<<(Print& o,navCmd cmd) {
-    return o<<"{"<<cmd.cmd<<","<<cmd.param<<"}";
-  }
-
-  Print& Menu::operator<<(Print& o,colorDefs c) {
-    switch(c) {
-      case bgColor:o<<"bgColor";break;
-      case fgColor:o<<"fgColor";break;
-      case valColor:o<<"valColor";break;
-      case unitColor:o<<"unitColor";break;
-      case cursorColor:o<<"cursorColor";break;
-      case titleColor:o<<"titleColor";break;
-      default:o<<"color?";break;
-    }
-    return o;
-  };
-
-  Print& Menu::operator<<(Print& o,idleEvent e) {
-    switch(e) {
-      case idleStart:o<<"idleStart";break;
-      case idling:o<<"idling";break;
-      case idleEnd:o<<"idleEnd";break;
-      default: o<<"idelEvent?"<<(int)e;break;
-    }
-    return o;
-  }
-
-  Print& Menu::operator<<(Print& o,systemStyles s) {
-    if (s==_noStyle) o<<"_noStyle";
-    else {
-      bool first=true;
-      if (s&_menuData) {o<<"_menuData";first=false;}
-      if (s&_canNav) {o<<(first?"":"|")<<"_canNav";first=false;}
-      if (s&_parentDraw) {o<<(first?"":"|")<<"_parentDraw";first=false;}
-      if (s&_isVariant) {o<<(first?"":"|")<<"_isVariant";first=false;}
-    }
-    return o;
-  }
-
-  // Print& Menu::operator<<(Print& o,prompt &p) {
-  //   print_P(o,p.getText(),-1);
-  //   return o;
-  // }
-#endif
diff --git a/src/menuBase.h b/src/menuBase.h
deleted file mode 100644
index 5798582d..00000000
--- a/src/menuBase.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Sept. 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-base for menu library
-definitions and enumerations
-
-www.r-site.net
-
-***/
-
-// #define MENU_DEBUG
-//DRAW_2D adds 260 bytes to flash
-//#define DRAW_2D
-
-#ifndef RSITE_ARDUINO_MENU_SYSTEM_BASE
-  #define RSITE_ARDUINO_MENU_SYSTEM_BASE
-
-  // #define MENU_ASYNC
-  // #define MENU_FMT_WRAPS
-
-  #ifdef MENU_DEBUG
-    extern bool debugFlag;
-    extern const char* libMemMode;
-  #endif
-
-  #include <Arduino.h>
-  #ifndef assert
-    #define assert(x)
-  #endif
-  #include "macros.h"
-
-  #define _MAX(a,b) (((a)>(b))?(a):(b))
-
-  // #define MENU_VERSION 4
-  // #define MENU_REVISION 4.9
-
-  #ifndef MENU_DEBUG_OUT
-    #define MENU_DEBUG_OUT Serial
-  #endif
-
-  namespace Menu {
-    //menu structure objects
-    class menuIn;
-    class menuOut;
-    class panel;
-    class panelsList;
-    class navNode;
-    class navRoot;
-    class prompt;
-    template<typename T> class menuField;
-    //struct menuNodeShadow;
-    class menuNode;
-    class menu;
-    template<typename T> class menuVariant;
-    template<typename T> class toggle;
-    template<typename T> class select;
-    template<typename T> class choose;
-
-    #ifdef __AVR_ARCH__
-      typedef int8_t idx_t;//int8_t on AVR's
-    #else
-      typedef int16_t idx_t;//int16_t on non AVR's
-    #endif
-
-    #if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-      idx_t print_P(Print& s,const char* at,idx_t sz=0);
-    #endif
-    idx_t print_P(menuOut& s,const char* at,idx_t sz=0);
-
-    enum result {proceed=0,quit};
-    enum systemStyles {
-      _noStyle=0,
-      _menuData=1,
-      _canNav=1<<1,
-      _parentDraw=1<<2,
-      _isVariant=1<<3,
-      _asPad=1<<4,
-      _Exit=1<<5
-    };
-    //showTitle and noTitle override the default
-    enum styles {
-      noStyle=0,
-      wrapStyle=1,
-      showTitle=2,
-      noTitle=4
-    };//,dontEnter=2};
-    //representing parsed input codes (can be used with switch/case)
-    enum navCmds {
-      noCmd=0,
-      escCmd,
-      enterCmd,
-      upCmd,
-      downCmd,
-      leftCmd,
-      rightCmd,
-      idxCmd,
-      selCmd,
-      scrlUpCmd,
-      scrlDownCmd
-    };
-    struct navCmd {
-      navCmds cmd;
-      idx_t param;
-      inline navCmd(navCmds cmd):cmd(cmd),param(-1) {}
-      inline navCmd(navCmds cmd,idx_t p):cmd(cmd),param(p) {}
-      inline bool operator==(navCmds n) const {return cmd==n;}
-      inline operator navCmds() const {return cmd;}
-    };
-
-    navCmds getCmd(String &name);
-
-    //----------------------------------------------------
-    //events generated by the menu system
-    enum eventMask {
-      noEvent=0,//just ignore all stuff
-      activateEvent=1,//this item is about to be active (system event)
-      enterEvent=1<<1,//entering navigation level (this menu is now active)
-      exitEvent=1<<2,//leaving navigation level
-      returnEvent=1<<3,//TODO:entering previous level (return)
-      focusEvent=1<<4,//element just gained focus
-      blurEvent=1<<5,//element about to lose focus
-      selFocusEvent=1<<6,//TODO:child just gained focus
-      selBlurEvent=1<<7,//TODO:child about to lose focus
-      updateEvent=1<<8,//Field value has been updated
-      anyEvent=~0
-    };
-    //events for the idle function
-    enum idleEvent {idleStart,idling,idleEnd};
-
-    //color defs, then indexing by selected and enabled status
-    enum colorDefs {
-      bgColor=0,
-      fgColor,
-      valColor,
-      unitColor,
-      cursorColor,
-      titleColor,
-      nColors//total number of colors
-    };
-
-    //this defines an array of disabled and enabled colors of yet unspecified color format C
-    template<typename C>
-    struct colorDef {
-      C disabled[2];
-      C enabled[3];
-    };
-
-    enum status {disabledStatus=0,enabledStatus=1};
-
-    #define SYS_FUNC_PARAMS eventMask event, navNode& nav, prompt &item
-    #define SYS_FUNC_VALUES event,nav,item
-    #define FUNC_PARAMS eventMask event, navNode& nav, prompt &item
-    #define FUNC_VALUES event,nav,item
-
-    //callback function type
-    typedef result (*callback)(FUNC_PARAMS);
-    typedef void (*vCall)(FUNC_PARAMS);//now also accept void return
-
-    //functions to hook as common prompt actions
-    result doNothing();//just proceed with menu
-    result doExit();//do not enter a menu or exit the current one
-
-    //idle function  type
-    typedef result (*idleFunc)(menuOut& o,idleEvent);
-    result inaction(menuOut& o,idleEvent e);//default idle function
-
-    //template<void (*A)(eventMask event, navNode& nav, prompt &item, Stream &in)> result callCaster(eventMask event, navNode& nav, prompt &item, Stream &in);
-    template<void (*A)(eventMask event, navNode& nav, prompt &item)> result callCaster(eventMask event, navNode& nav, prompt &item);
-    template<void (*A)(eventMask event, navNode& nav)> result callCaster(eventMask event, navNode& nav);
-    template<void (*A)(eventMask event)> result callCaster(eventMask event);
-    template<void (*A)()> result callCaster();
-
-    //menu element associated function (called for all element registered events)
-    struct actionRaw {callback hFn;};
-    class action {
-      public:
-        callback hFn;//the hooked callback function
-        inline action() {}
-        //inline action(void (*f)()):hFn((callback)f) {}
-        inline action(result (*f)()):hFn((callback)f) {}
-        inline action(result (*f)(eventMask)):hFn((callback)f) {}
-        inline action(result (*f)(eventMask,navNode&)):hFn((callback)f) {}
-        // inline action(result (*f)(eventMask,navNode&,prompt&)):hFn((callback)f) {}
-        //inline action(result (*f)(eventMask,navNode&,prompt&,Stream&)):hFn((callback)f) {}
-        inline action(callback f):hFn(f) {}
-        inline result operator()(FUNC_PARAMS) const {return ((callback)memPtr(hFn))(FUNC_VALUES);}
-    };
-
-    extern action noAction;
-
-    //config
-    ///////////////////////////////////////////////////////////////////////////
-    struct navCode {navCmds cmd;char ch;};
-    typedef navCode navCodesDef[10];
-    extern const navCodesDef defaultNavCodes;
-
-    struct config {
-      config(
-        char ecur='>',
-        char dcur='-',
-        const navCodesDef &nc=defaultNavCodes,
-        bool invKeys=true
-      ):selectedCursor(ecur),
-      disabledCursor(dcur),
-      navCodes(nc),
-      invertFieldKeys(invKeys) {}
-      //NOTE:this can be output specific
-      char selectedCursor;//='>';
-      char disabledCursor;//='-';
-      const navCodesDef &navCodes;//=defaultNavCodes;
-      bool invertFieldKeys;
-      bool useNavChars=true;//textFields should watch out for nav char in the stream (can write then on keybeord if true)
-      inline char getCmdChar(navCmds cmd) const {return navCodes[cmd].ch;}//return character assigned to this command
-    };
-
-    extern config defaultOptions;
-    extern config* options;
-
-    #ifdef DRAW_2D
-      typedef class Area {
-        protected:
-          inline Area op(Area& (Area::*o)(const Area&),const Area&p) const {
-            Area tmp(*this);
-            return (tmp.*o)(p);
-          }
-        public:
-          idx_t w;
-          idx_t h;
-          inline Area() {}
-          inline Area(idx_t w,idx_t h):w(w),h(h) {}
-          inline Area(const Area& o):w(o.w),h(o.h) {}
-          inline Area(idx_t x):w(x),h(0) {}
-          inline operator idx_t() {return w;}
-          inline Area  operator-() {return Area(-h,-w);}
-          inline Area& operator+=(const Area& o) {w+=o.w;h+=o.h;return *this;}
-          inline Area& operator-=(const Area& o) {w-=o.w;h-=o.h;return *this;}
-          inline Area& operator&=(const Area& o) {
-            if (w<o.w) w=o.w;
-            if (h<o.h) h=o.h;
-            return *this;
-          }
-          inline Area  operator+ (const Area& o) const {return op(&Area::operator+=,o);}
-          inline Area  operator- (const Area& o) const {return op(&Area::operator-=,o);}
-      } Used;
-    #else
-      typedef idx_t Used;
-    #endif
-
-    #if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-      Print& operator<<(Print& o,bool b);
-      Print& operator<<(Print& o,navCmds cmd);
-      Print& operator<<(Print& o,navCmd cmd);
-      Print& operator<<(Print& o,result cmd);
-      Print& operator<<(Print& o,eventMask e);
-      Print& operator<<(Print& o,colorDefs c);
-      Print& operator<<(Print& o,idleEvent e);
-      Print& operator<<(Print& o,systemStyles s);
-      // Print& operator<<(Print& o,prompt &p);
-    #endif
-
-  }
-
-#endif
diff --git a/src/menuDefs.h b/src/menuDefs.h
deleted file mode 100644
index 1c6af38b..00000000
--- a/src/menuDefs.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- C++ -*- */
-#pragma once
-
-#include <Arduino.h>
-// #define MENU_ASYNC
-// #define MENU_FMT_WRAPS
-// #define USE_PGM
-// #define USE_RAM
-// #define MENU_DEBUG
-
-#include "macros.h"
-#include "menuBase.h"
-#include "shadows.h"
-
-using namespace Menu;
-
-#ifdef MENU_DEBUG
-  String& operator<<(String&s,prompt &p);
-  Stream& operator<<(Stream&o,prompt& p);
-  Print& operator<<(Print&o,prompt& p);
-#endif
-
-#if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-  #ifndef ios_h
-    #ifndef ARDUINO_STREAMING
-      //https://github.com/neu-rah/streamFlow
-      #include <streamFlow.h>
-    #else
-      //https://github.com/scottdky/Streaming
-      #include <Streaming.h>
-    #endif
-  #endif
-#endif
-
-
-#if defined(MENU_DEBUG) && defined(TRACE)
-  #define trace(x) x
-#else
-  #define trace(x)
-#endif
-#ifdef MENU_DEBUG
-  #define _trace(x) x
-#else
-  #define _trace(x)
-#endif
-#ifndef MENU_RELEASE
-  #define __trace(x) x
-#else
-  #define __trace(x)
-#endif
-
-namespace Menu {
-  extern const char* numericChars;
-  result maxDepthError(menuOut& o,idleEvent e);
-}
-
-#include "items.h"
-#include "menuIo.h"
-#include "nav.h"
diff --git a/src/menuIO/I2CkeypadIn.h b/src/menuIO/I2CkeypadIn.h
deleted file mode 100644
index 2c1af319..00000000
--- a/src/menuIO/I2CkeypadIn.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* -*- C++ -*- */
-/**************
-Jan. 2018 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-I2C keypad driver
-using
-   https://github.com/whatnick/i2ckeypad
-
-   Note: you may be need to adjust keypad-to-pcf8574 pin mappings and keymap in i2ckeypad.cpp for your specific keypad.
-
-***/
-
-#ifndef RSITE_I2CKEYPAD_DEF_H
-  #define RSITE_I2CKEYPAD_DEF_H
-  #include "../menuDefs.h"
-
-  #include <i2ckeypad.h>
-  namespace Menu {
-
-    class I2CkeypadIn:public menuIn {
-    public:
-      char key=0;
-      i2ckeypad * in;
-      I2CkeypadIn(i2ckeypad * in):in(in) {}
-      int available(void) {
-		  return peek()!=0;
-	  }
-      int peek(void) { 
-		  return key != 0 ? key : (key=in->get_key()) ?key : 0;
-	  }
-      int read() {
-        if (key != 0) {
-          char k=key;
-          key=0;
-          return k;
-        }
-        return available()?read():0;
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-  };
-#endif
diff --git a/src/menuIO/OzOledAsciiOut.h b/src/menuIO/OzOledAsciiOut.h
deleted file mode 100644
index 438fd3c1..00000000
--- a/src/menuIO/OzOledAsciiOut.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- C++ -*- */
-
-//using OzOled
-//using https://github.com/kdkanishka/ozoled-oled-display-096-i2c-driver-library
-
-#ifndef RSITE_ARDUINO_MENU_OZOLEDASCIIOUT
-#define RSITE_ARDUINO_MENU_OZOLEDASCIIOUT
-
-  #include "../menuDefs.h"
-  // #include <Wire.h>
-  // #include <LCD.h>
-
-  namespace Menu {
-
-    class OzOledAsciiOut:public menuOut {
-      public:
-        OzOLED* device;
-        inline OzOledAsciiOut(OzOLED* o,idx_t *t,panelsList &p,menuOut::styles s=menuOut::minimalRedraw)
-          :menuOut(t,p,s),device(o) {}
-          size_t write(uint8_t ch) override { device->printChar(ch); return 1;}
-        void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-        	setCursor(0,ln,panelNr);
-        	for(int n=0;n<maxX();n++) print(' ');
-        	setCursor(0,ln,panelNr);
-        }
-        void clear() override {
-          device->clearDisplay();
-          panels.reset();
-        }
-        void clear(idx_t panelNr) override {
-          const panel p=panels[panelNr];
-          fill(p.x,p.y,p.x+p.w-1,p.y+p.h-1);
-          setCursor(0,0,panelNr);
-          panels.nodes[panelNr]=NULL;
-        }
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-          const panel p=panels[panelNr];
-          device->setCursorXY(p.x+x,p.y+y);
-        }
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/PCF8574KeyIn.h b/src/menuIO/PCF8574KeyIn.h
deleted file mode 100644
index 6aa53529..00000000
--- a/src/menuIO/PCF8574KeyIn.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- C++ -*- */
-
-/**************
-todo: write description
-available keys from 0 to 7 correspond with pcf8574 input pins from p0 to p7
-
-example:
-
-#include <menuIO/PCF8574KeyIn.h>
-
-#define K_UP     0
-#define K_RIGHT  1
-#define K_LEFT   2
-#define K_DOWN   3
-
-#define K_ESC    4
-#define K_ENTER  5
-
-keyMap myBtn_map[]={
-                      {K_UP,options->getCmdChar(upCmd)},
-                      {K_RIGHT,options->getCmdChar(rightCmd)},
-                      {K_LEFT,options->getCmdChar(leftCmd)},
-                      {K_DOWN,options->getCmdChar(downCmd)},
-                      {K_ESC,options->getCmdChar(escCmd)},
-                      {K_ENTER,options->getCmdChar(enterCmd)}
-                    };
-PCF8574KeyIn<6> myButton(myBtn_map,Wire);
-
-***/
-
-#ifndef __PCF8574KeyIn_h__
-  #define __PCF8574KeyIn_h__
-
-  #include "../menuDefs.h"
-  #include <Wire.h>
-
-  namespace Menu {
-
-    #include "keyMapDef.h"
-
-    #ifndef BOUNCE_TICK
-    #define BOUNCE_TICK 30
-    #endif
-
-    //if you hold/repeat a key for this ammount of time we will consider it an escape
-    #ifndef ESCAPE_TIME
-    #define ESCAPE_TIME 1500
-    #endif
-    //emulate a stream keyboard, this is not using interrupts as a good driver should do
-    // AND is not using a buffer either!
-    template <int N,int _dev=0x20>                 //default pcf8574 address=0x20
-    class PCF8574KeyIn:public menuIn {
-    private:
-      bool modeEdit;
-    public:
-      keyMap* keys;
-      TwoWire& dev;
-      int lastkey;
-      unsigned long pressMills=0;
-      PCF8574KeyIn(keyMap k[],TwoWire& dev=Wire):keys(k),dev(dev),lastkey(-1) {}
-      void setFieldMode(bool mode) override {
-        modeEdit = mode;
-      }
-      int available(void) {
-        int ch=peek();
-        if (lastkey==-1) {
-          lastkey=ch;
-          pressMills=millis();
-        }
-        else if (ch == -1 && millis()-pressMills < BOUNCE_TICK)
-        {
-          lastkey = -1;  //released = it's bounce. reset lastkey
-          return 0;
-        }
-        else if (ch != -1 && millis()-pressMills > BOUNCE_TICK) return 1;
-        else if (ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME) return 1;
-
-        if (ch==lastkey) return 0;
-
-        return 1;
-      }
-      int peek(void) {
-        //MENU_DEBUG_OUT<<"peek"<<endl;
-        dev.requestFrom(_dev, 1);
-        uint8_t val = dev.read();
-        for(int n=0;n<N;n++) {
-          int8_t pin = keys[n].pin;
-          int8_t code = keys[n].code;
-          if (((val)&1<<pin)==0) {
-            //MENU_DEBUG_OUT<<"key "<<pin<<" pressed"<<endl;
-            if (modeEdit == false && (code == options->getCmdChar(upCmd) || navCmds(code) == options->getCmdChar(downCmd))) {
-              //if we navigate on menu then return code up/down (left/right) reversed as down/up (right/left)
-              return (code==options->getCmdChar(upCmd)?options->getCmdChar(downCmd):options->getCmdChar(upCmd));
-            }
-            else
-            {
-              //else if we inside edit field then return all key codes as is
-              return code;
-            }
-          }
-        }
-        return -1;
-      }
-      int read() {
-        //MENU_DEBUG_OUT<<"read"<<endl;
-        int ch=peek();
-        if (ch==lastkey) return -1;
-        int tmp=lastkey;
-        bool longPress=ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME;
-        //MENU_DEBUG_OUT<<"read lastkey="<<lastkey<<" ch="<<ch<<endl;
-        //MENU_DEBUG_OUT<<"down time:"<<millis()-pressMills<<endl;
-        pressMills=millis();
-        lastkey=ch;
-        return longPress?options->getCmdChar(escCmd):tmp;//long press will result in escape
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/PCF8574Out.h b/src/menuIO/PCF8574Out.h
deleted file mode 100644
index a9ec741f..00000000
--- a/src/menuIO/PCF8574Out.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- C++ -*- */
-
-//using Matthias Hertel driver https://github.com/mathertel/LiquidCrystal_PCF8574
-
-#ifndef RSITE_ARDUINO_MENU_PCF8574OUT
-  #define RSITE_ARDUINO_MENU_PCF8574OUT
-
-  // #ifndef ARDUINO_SAM_DUE
-    #include "../menuDefs.h"
-    #include <Wire.h>
-    #include <LiquidCrystal_PCF8574.h>
-
-    namespace Menu {
-
-      class lcdOut:public cursorOut {
-        public:
-          LiquidCrystal_PCF8574* device;
-          inline lcdOut(LiquidCrystal_PCF8574* o,idx_t *t,panelsList &p,menuOut::styles s=menuOut::minimalRedraw)
-            :cursorOut(t,p,s),device(o) {}
-          size_t write(uint8_t ch) override {return device->write(ch);}
-          void clear() override {
-            device->clear();
-            panels.reset();
-          }
-          void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-            const panel p=panels[panelNr];
-            device->setCursor(p.x+x,p.y+y);
-          }
-          idx_t startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0) override {return 0;}
-          idx_t endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0) override {return 0;}
-          idx_t editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr=0) override {
-            trace(MENU_DEBUG_OUT<<"lcdOut::editCursor "<<x<<","<<y<<endl);
-            //text editor cursor
-            device->noBlink();
-            device->noCursor();
-            if (editing) {
-              device->setCursor(x, y);
-              if (charEdit) device->cursor();
-              else device->blink();
-            }
-            return 0;
-          }
-
-      };
-
-    }//namespace Menu
-
-  #endif
-// #endif
diff --git a/src/menuIO/SSD1306AsciiOut.h b/src/menuIO/SSD1306AsciiOut.h
deleted file mode 100644
index e24ee0a8..00000000
--- a/src/menuIO/SSD1306AsciiOut.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- C++ -*- */
-
-//using SSD1306Ascii
-//https://github.com/greiman/SSD1306Ascii
-
-#ifndef RSITE_ARDUINO_MENU_SSD1306ASCIIOUT
-  #define RSITE_ARDUINO_MENU_SSD1306ASCIIOUT
-
-  #include "../menuDefs.h"
-  // #include <Wire.h>
-  // #include <LCD.h>
-
-  namespace Menu {
-
-    class SSD1306AsciiOut:public gfxOut {
-      public:
-        SSD1306Ascii* device;
-        SSD1306AsciiOut(
-          SSD1306Ascii* o,
-  				idx_t* t,
-  				panelsList &p,
-  				idx_t resX=6,
-  				idx_t resY=1,
-          menuOut::styles s=menuOut::minimalRedraw
-  			):gfxOut(resX,resY,t,p,s),device(o) {}
-        void init() {
-          resX=device->fontHeight();
-          resY=device->fontWidth();
-          fontMarginX=0;
-          fontMarginY=0;
-        }
-        size_t write(uint8_t ch) override {return device->write(ch);}
-        void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-          const panel p=panels[panelNr];
-          int y=(p.y+ln)*resY;
-          device->clear(resX*p.x,resX*(p.x+maxX(panelNr))-1,y,y+resY-1);
-        }
-        void clear() override {
-          trace(Serial<<"clear!!"<<endl;);
-          device->clear();
-          panels.reset();
-        }
-        void clear(idx_t panelNr) override {
-          const panel p=panels[panelNr];
-          trace(Serial<<"clear panel!! "<<panelNr<<"{"<<p.x<<","<<p.y<<","<<p.w<<","<<p.h<<"}"<<endl;);
-          device->clear(resX*p.x,resX*(p.x+p.w)-1,resY*p.y,resY*(p.y+p.h)-1);
-          // setCursor(0,0,panelNr);
-          panels.nodes[panelNr]=NULL;
-        }
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-          const panel p=panels[panelNr];
-          device->setCursor((p.x+x)*resX,(p.y+y)*resY);
-        }
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/TFT_HX8357Out.h b/src/menuIO/TFT_HX8357Out.h
deleted file mode 100644
index fa278a88..00000000
--- a/src/menuIO/TFT_HX8357Out.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Feb.2018 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-menu with TFT_HX8357 driver https://github.com/Bodmer/TFT_HX8357
-www.r-site.net
-
-***/
-#ifndef RSITE_TFT_HX8357_DEF_H
-	#define RSITE_TFT_HX8357_DEF_H
-  #include <TFT_HX8357.h>
-	#include "../menuDefs.h"
-
-namespace Menu {
-
-		#define RGB565(r,g,b) ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)))
-
-	  class tftHX8257Out:public gfxOut {
-	    public:
-				TFT_HX8357& gfx;
-				const colorDef<uint16_t> (&colors)[nColors];
-		    tftHX8257Out(TFT_HX8357& gfx,const colorDef<uint16_t> (&c)[nColors],idx_t* t,panelsList &p,idx_t resX=6,idx_t resY=9)
-					:gfxOut(resX,resY,t,p),gfx(gfx),colors(c) {}
-					//:gfxOut(gfx.width()/resX,gfx.height()/resY,resX,resY,false),colors(c),gfx(gfx) {}
-
-				size_t write(uint8_t ch) override {return gfx.write(ch);}
-
-				inline uint16_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-          return memWord(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-        }
-
-				void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool e=false) override {
-					gfx.setTextColor(getColor(c,selected,s,e));
-				}
-
-				void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,(p.y+ln)*resY,p.maxX()*resX,resY,getColor(color,selected,stat,edit));
-		    	//setCursor(0,ln);
-		    }
-		    void clear() override {
-					panels.reset();
-					gfx.fillScreen(getColor(bgColor,false,enabledStatus,false));
-		    	setCursor(0,0);
-					setColor(fgColor);
-				}
-
-				void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.drawRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void clear(idx_t panelNr) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,p.y*resY,p.w*resX,p.h*resY,getColor(bgColor,false,enabledStatus,false));
-					panels.nodes[panelNr]=NULL;
-				}
-
-		    void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					gfx.setCursor((p.x+x)*resX,(p.y+y)*resY+fontMarginY);
-				}
-
-				void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					// gfxOut::drawCursor(ln,selected,stat);
-					gfx.drawRect(p.x*resX,(p.y+ln)*resY,maxX()*resX,resY,getColor(cursorColor,selected,enabledStatus,false));
-				}
-	  };
-
-}; //namespace adaGfxOut
-#endif
diff --git a/src/menuIO/TFT_eSPIOut.h b/src/menuIO/TFT_eSPIOut.h
deleted file mode 100644
index 758e6f4b..00000000
--- a/src/menuIO/TFT_eSPIOut.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- C++ -*- */
-/********************
-by:
-  https://github.com/fa1ke5 (Jan. 2019)
-	posted here: https://github.com/neu-rah/ArduinoMenu/issues/225 (thank you)
-based on:
-  Rui Azevedo - ruihfazevedo(@rrob@)gmail.com (Sept. 2014)
-
-Use graphics screens (adafruit library based) as menu output
-www.r-site.net
-
-***/
-#pragma once
-
-#ifndef RSITE_ARDUINOP_MENU_TFT_ESPI
-	#define RSITE_ARDUINOP_MENU_TFT_ESPI
-	#include <TFT_eSPI.h>
-	#include "../menuDefs.h"
-
-// usage:
-// #include <TFT_eSPI.h>
-// TFT_eSPI gfx = TFT_eSPI();
-// #include <menu.h>
-// #include <menuIO/TFT_eSPIOut.h>
-// TTFT_eSPI gfx = TFT_eSPI();
-
-namespace Menu {
-
-		#define RGB565(r,g,b) ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)))
-
-	  class TFT_eSPIOut:public gfxOut {
-	    public:
-				TFT_eSPI& gfx;
-				const colorDef<uint16_t> (&colors)[nColors];
-		    TFT_eSPIOut(TFT_eSPI& gfx,const colorDef<uint16_t> (&c)[nColors],idx_t* t,panelsList &p,idx_t resX=6,idx_t resY=9)
-					:gfxOut(resX,resY,t,p),gfx(gfx),colors(c) {}
-					//:gfxOut(gfx.width()/resX,gfx.height()/resY,resX,resY,false),colors(c),gfx(gfx) {}
-
-				size_t write(uint8_t ch) override {return gfx.write(ch);}
-
-				inline uint16_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-          return memWord(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-        }
-
-				void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool e=false) override {
-					gfx.setTextColor(getColor(c,selected,s,e));
-				}
-
-				void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,(p.y+ln)*resY,p.maxX()*resX,resY,getColor(color,selected,stat,edit));
-		    	//setCursor(0,ln);
-		    }
-		    void clear() override {
-					panels.reset();
-					gfx.fillScreen(getColor(bgColor,false,enabledStatus,false));
-		    	setCursor(0,0);
-					setColor(fgColor);
-				}
-
-				void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.drawRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void clear(idx_t panelNr) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,p.y*resY,p.w*resX,p.h*resY,getColor(bgColor,false,enabledStatus,false));
-					panels.nodes[panelNr]=NULL;
-				}
-
-		    void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					gfx.setCursor((p.x+x)*resX,(p.y+y)*resY+fontMarginY);
-				}
-
-				void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					// gfxOut::drawCursor(ln,selected,stat);
-					gfx.drawRect(p.x*resX,(p.y+ln)*resY,maxX()*resX,resY,getColor(cursorColor,selected,enabledStatus,false));
-				}
-	  };
-
-};
-#endif
diff --git a/src/menuIO/U8GLibOut.h b/src/menuIO/U8GLibOut.h
deleted file mode 100644
index 16f38a18..00000000
--- a/src/menuIO/U8GLibOut.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- C++ -*- */
-
-/********************
-Sept. 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Original from: https://github.com/christophepersoz
-
-Use graphics screens as menu output, based on U8GLIB graphic display
-www.r-site.net
-
- printPrompt(), Added posX to take into account ox via menu.ox and setPosition(ox,oy), need to update other files to support that.
-
-***/
-#ifndef RSITE_ARDUINOP_MENU_U8G
-	#define RSITE_ARDUINOP_MENU_U8G
-  #include <U8glib.h>
-	#include "menuDefs.h"
-
-  namespace Menu {
-
-    class u8gLibOut:public gfxOut {
-      public:
-	      U8GLIB& gfx;
-				//int8_t fontMarginY=1;
-				const colorDef<uint8_t> (&colors)[nColors];
-	      u8gLibOut(
-					U8GLIB& gfx,
-					const colorDef<uint8_t> (&c)[nColors],
-					idx_t* t,
-					panelsList &p,
-					idx_t resX=6,
-					idx_t resY=9
-				) :gfxOut(resX,resY,t,p,(menuOut::styles)(menuOut::redraw|menuOut::rasterDraw)),gfx(gfx),colors(c) {
-	        	gfx.setFontPosBottom(); // U8Glib font positioning
-	      }
-
-				size_t write(uint8_t ch) override {return gfx.write(ch);}
-				inline uint8_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-          return memByte(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-        }
-
-				void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool edit=false) override {
-					gfx.setColorIndex(getColor(c,selected,s,edit));
-				}
-
-				void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					setColor(color,selected,stat,edit);
-					gfx.drawBox(p.x*resX,(p.y+ln)*resY,maxX()*resX,resY/*+(fontMarginY<<1)*/);
-	      }
-	      void clear() override {
-					setCursor(0,0);
-					setColor(fgColor);
-					panels.reset();
-	      }
-				void clear(idx_t panelNr) override {
-					const panel p=panels[panelNr];
-					setColor(bgColor,false,enabledStatus,false);
-					gfx.drawBox(p.x*resX,p.y*resY,p.w*resX,p.h*resY/*+(fontMarginY<<1)*/);
-					panels.nodes[panelNr]=NULL;
-				}
-				void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					setColor(c,selected,stat,edit);
-					gfx.drawFrame((p.x+x)*resX,(p.y+y-1)*resY,w*resX,h*resY/*+(fontMarginY<<1)*/);
-				}
-
-				void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					setColor(c,selected,stat,edit);
-					gfx.drawBox((p.x+x)*resX,(p.y+y-1)*resY,w*resX,h*resY/*+(fontMarginY<<1)*/);
-				}
-
-	      void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-          gfx.setPrintPos((p.x+x)*resX,(p.y+y+1)*resY-fontMarginY);
-	      }
-
-				void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					// gfxOut::drawCursor(ln,selected,stat);
-					// if (stat==disabledStatus) {
-					setColor(cursorColor,selected,stat);
-					// 	gfx.drawFrame(p.x*resX,(p.y+ln)*resY,maxX()*resX,resY/*+(fontMarginY<<1)*/);
-					// }
-          gfx.drawFrame(p.x*resX /*- fontMarginY*/,(p.y+ln)*resY /*- fontMarginY*/,maxX()*resX /*+ fontMarginY*/ /*+ fontMarginY*/,resY /*+ fontMarginY*/ /*+ fontMarginY*/);
-				}
-  	};
-}
-#endif //RSITE_ARDUINOP_MENU_LCD
diff --git a/src/menuIO/U8x8Out.h b/src/menuIO/U8x8Out.h
deleted file mode 100644
index 9e60a264..00000000
--- a/src/menuIO/U8x8Out.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* -*- C++ -*- */
-
-/***********
-U8x8 Driver
-Sep. 2017 Rui Azevedo (ruihfazevedo@rrob@gmail.com)
-Based on: Stephen Denne https://github.com/datacute U8G2 Driver
-*/
-
-#ifndef RSITE_ARDUINO_MENU_U8X8
-  #define RSITE_ARDUINO_MENU_U8X8
-  #include "../menuDefs.h"
-  #include <U8x8lib.h>
-
-  namespace Menu {
-
-    class U8x8Out:public cursorOut {
-      public:
-        U8X8& device;
-        inline U8x8Out(U8X8& o,idx_t *t,panelsList &p,menuOut::styles s=minimalRedraw)
-          :cursorOut(t,p,s),device(o) {}
-        size_t write(uint8_t ch) override {return device.write(ch);}
-        void clear() override {
-          device.clear();
-          panels.reset();
-        }
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-          const panel p=panels[panelNr];
-          device.setCursor(p.x+x,p.y+y);
-        }
-        virtual idx_t startCursor(bool charEdit) {device.setInverseFont(0);return 0;}
-        virtual idx_t endCursor(bool charEdit) {device.setInverseFont(0);return 0;}
-        virtual idx_t editCursor(idx_t x,idx_t y,bool editing,bool charEdit) {return 0;}
-    };
-
-  }//namespace Menu
-#endif
diff --git a/src/menuIO/UCGLibOut.h b/src/menuIO/UCGLibOut.h
deleted file mode 100644
index 1ec8407b..00000000
--- a/src/menuIO/UCGLibOut.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* -*- C++ -*- */
-
-/********************
-Sep. 2017 Rui Azevedo (ruihfazevedo@rrob@gmail.com)
-Based on: Stephen Denne https://github.com/datacute U8G2 Driver
-
-Use graphics screens as menu output, based on U8G2 graphic display
-www.r-site.net
-***/
-
-#ifndef RSITE_ARDUINOP_MENU_UCGLIB
-#define RSITE_ARDUINOP_MENU_UCGLIB
-#include <Ucglib.h>
-#include "menuDefs.h"
-
-namespace Menu {
-
-	struct rgb{
-		uint8_t r;
-		uint8_t g;
-		uint8_t b;
-		inline rgb(uint8_t r,uint8_t g,uint8_t b):r(r),g(g),b(b) {}
-	};
-
-	class UCGLibOut:public gfxOut {
-		public:
-			Ucglib& gfx;
-			int8_t offsetX=0;
-			int8_t offsetY=0;
-			const colorDef<rgb> (&colors)[nColors];
-			UCGLibOut(
-				Ucglib& gfx,
-				const colorDef<rgb> (&c)[nColors],
-				idx_t* t,
-				panelsList &p,
-				idx_t resX=6,
-				idx_t resY=9,
-				idx_t offsetX=0,
-				idx_t offsetY=0
-			) :gfxOut(resX,resY,t,p,menuOut::minimalRedraw),gfx(gfx),colors(c) {
-					gfx.setFontPosBottom(); // U8Glib font positioning
-					this->offsetX=offsetX;
-					this->offsetY=offsetY;
-			}
-
-			size_t write(uint8_t ch) override {return gfx.write(ch);}
-
-			inline rgb getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-				rgb* cor=(rgb*)&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]);
-				return rgb(memByte(&cor->r),memByte(&cor->g),memByte(&cor->b));
-			}
-
-			void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool edit=false) override {
-				rgb cor=getColor(c,selected,s,edit);
-				gfx.setColor(cor.r,cor.g,cor.b);
-			}
-
-			void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-				const panel p=panels[panelNr];
-				setColor(color,selected,stat,edit);
-				gfx.drawBox(p.x*resX + offsetX - 1,(p.y+ln)*resY + offsetY /*- fontMarginY*/,maxX()*resX /*+ fontMarginY*/ /*+ fontMarginY*/,resY /*+ fontMarginY*/ /*+ fontMarginY*/);
-				//setCursor(0,ln);
-			}
-			void clear() override {
-				setCursor(0,0);
-				setColor(fgColor);
-				panels.reset();
-			}
-			void clear(idx_t panelNr) override {
-				const panel p=panels[panelNr];
-				setColor(bgColor,false,enabledStatus,false);
-				gfx.drawBox(p.x*resX + offsetX,p.y*resY + offsetY,p.w*resX,p.h*resY);
-				//clear();
-				panels.nodes[panelNr]=NULL;
-			}
-			void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-				const panel p=panels[panelNr];
-				gfx.drawFrame((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY);
-			}
-
-			void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-				const panel p=panels[panelNr];
-				setColor(c,selected,stat,edit);
-				gfx.drawBox((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY);
-			}
-
-			void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-				const panel p=panels[panelNr];
-				gfx.setPrintPos((p.x+x)*resX + offsetX,(p.y+y+1)*resY-fontMarginY + offsetY);//+1 because font pos bottom
-			}
-
-			void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-				const panel p=panels[panelNr];
-				// gfxOut::drawCursor(ln,selected,stat);
-				setColor(cursorColor,selected,stat);
-				gfx.drawFrame(p.x*resX + offsetX ,(p.y+ln)*resY + offsetY ,maxX()*resX ,resY);
-			}
-	};
-}
-#endif //RSITE_ARDUINOP_MENU_U8G2
diff --git a/src/menuIO/adafruitGfxOut.h b/src/menuIO/adafruitGfxOut.h
deleted file mode 100644
index 40f69b88..00000000
--- a/src/menuIO/adafruitGfxOut.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-Use graphics screens (adafruit library based) as menu output
-www.r-site.net
-
-***/
-#ifndef RSITE_ARDUINOP_MENU_GFX
-	#define RSITE_ARDUINOP_MENU_GFX
-	#include <Adafruit_GFX.h>
-	#include "../menuDefs.h"
-
-namespace Menu {
-
-		#define RGB565(r,g,b) ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)))
-
-	  class adaGfxOut:public gfxOut {
-	    public:
-				Adafruit_GFX& gfx;
-				const colorDef<uint16_t> (&colors)[nColors];
-		    adaGfxOut(Adafruit_GFX& gfx,const colorDef<uint16_t> (&c)[nColors],idx_t* t,panelsList &p,idx_t resX=6,idx_t resY=9)
-					:gfxOut(resX,resY,t,p),gfx(gfx),colors(c) {}
-					//:gfxOut(gfx.width()/resX,gfx.height()/resY,resX,resY,false),colors(c),gfx(gfx) {}
-
-				size_t write(uint8_t ch) override {return gfx.write(ch);}
-
-				inline uint16_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-          return memWord(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-        }
-
-				void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool e=false) override {
-					gfx.setTextColor(getColor(c,selected,s,e));
-				}
-
-				void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,(p.y+ln)*resY,p.maxX()*resX,resY,getColor(color,selected,stat,edit));
-		    	//setCursor(0,ln);
-		    }
-		    void clear() override {
-					panels.reset();
-					gfx.fillScreen(getColor(bgColor,false,enabledStatus,false));
-		    	setCursor(0,0);
-					setColor(fgColor);
-				}
-
-				void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.drawRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void clear(idx_t panelNr) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,p.y*resY,p.w*resX,p.h*resY,getColor(bgColor,false,enabledStatus,false));
-					panels.nodes[panelNr]=NULL;
-				}
-
-		    void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					gfx.setCursor((p.x+x)*resX,(p.y+y)*resY+fontMarginY);
-				}
-
-				void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					// gfxOut::drawCursor(ln,selected,stat);
-					gfx.drawRect(p.x*resX,(p.y+ln)*resY,maxX()*resX,resY,getColor(cursorColor,selected,enabledStatus,false));
-				}
-	  };
-
-}; //namespace adaGfxOut
-#endif
diff --git a/src/menuIO/altKeyIn.h b/src/menuIO/altKeyIn.h
deleted file mode 100644
index d8c97161..00000000
--- a/src/menuIO/altKeyIn.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- C++ -*- */
-/**************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-quick and dirty keyboard driver
-metaprog keyboard driver where N is the number of keys
-all keys are expected to be a pin (buttons)
-we can have reverse logic (pull-ups) by entering negative pin numbers
-ex: -A0 means: pin A0 normally high, low when button pushed (reverse logic)
-
-***/
-
-#ifndef RSITE_KEYIN_DEF_H
-  #define RSITE_KEYIN_DEF_H
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    #include "altKeyMapDef.h"
-
-    //if you hold/repeat a key for this ammount of time we will consider it an escape
-    #ifndef ESCAPE_TIME
-    #define ESCAPE_TIME 1500
-    #endif
-    //emulate a stream keyboard, this is not using interrupts as a good driver should do
-    // AND is not using a buffer either!
-    template <int N>
-    class keyIn:public menuIn {
-    public:
-      keyMap* keys;
-      int lastkey;
-      unsigned long pressMills=0;
-      keyIn<N>(keyMap k[]):keys(k),lastkey(-1) {}
-      void begin() {
-        for(int n=0;n<N;n++)
-          pinMode(keys[n].pin,keys[n].mode);
-
-      }
-      int available(void) {
-        //MENU_DEBUG_OUT<<"available"<<endl;
-        int ch=peek();
-        if (lastkey==-1) {
-          lastkey=ch;
-          pressMills=millis();
-        } else if (ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME) return 1;
-        if (ch==lastkey) return 0;
-        return 1;
-        /*int cnt=0;
-        for(int n=0;n<N;n++) {
-          int8_t pin=keys[n].pin;
-          if (digitalRead(pin<0?-pin:pin)!=(pin<0) ) cnt++;
-        }
-        return cnt;*/
-      }
-      int peek(void) {
-        //MENU_DEBUG_OUT<<"peek"<<endl;
-        for(int n=0;n<N;n++) {
-          int8_t pin=keys[n].pin;
-		  uint8_t mode = keys[n].mode == INPUT_PULLUP ? LOW : HIGH;
-          if (digitalRead(pin) == mode ) return keys[n].code;
-        }
-        return -1;
-      }
-      int read() {
-        //MENU_DEBUG_OUT<<"read"<<endl;
-        int ch=peek();
-        if (ch==lastkey) return -1;
-        int tmp=lastkey;
-        bool longPress=ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME;
-        //MENU_DEBUG_OUT<<"read lastkey="<<lastkey<<" ch="<<ch<<endl;
-        //MENU_DEBUG_OUT<<"down time:"<<millis()-pressMills<<endl;
-        pressMills=millis();
-        lastkey=ch;
-        return longPress?options->getCmdChar(escCmd):tmp;//long press will result in escape
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/altKeyMapDef.h b/src/menuIO/altKeyMapDef.h
deleted file mode 100644
index 737c9a51..00000000
--- a/src/menuIO/altKeyMapDef.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* -*- C++ -*- */
-
-#ifndef RSITE_ARDUINO_MENU_KEYMAP
-  #define RSITE_ARDUINO_MENU_KEYMAP
-
-struct keyMap {
-  int8_t pin;
-  int8_t code;
-  uint8_t mode;
-};
-
-#endif
diff --git a/src/menuIO/analogAxisIn.h b/src/menuIO/analogAxisIn.h
deleted file mode 100644
index fbc95173..00000000
--- a/src/menuIO/analogAxisIn.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-analogAxisIn - analog joystick axis
-*/
-
-#ifndef RSITE_ARDUINO_MENU_ANALOG_JOYSTICK_INPUT
-  #define RSITE_ARDUINO_MENU_ANALOG_JOYSTICK_INPUT
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    template<
-      uint8_t pin,//axis pin number
-      uint8_t sensivity=5,
-      bool inv=false,//invert axis direction
-      int center=512,//calibration
-      int inertia=6,//prevent rest drift
-      int bufferSz=1,//how many clicks can accumulate
-      navCmds posCmd=upCmd,//what is sent by positive axis click
-      navCmds negCmd=downCmd//what is sent by negative axis click
-    > class analogAxis:public menuIn {
-      public:
-        bool field_mode=false;
-        virtual void setFieldMode(bool mode) {field_mode=mode;}
-        virtual bool fieldMode() const {return field_mode;}
-        int cnt=0;
-        long last=0;
-        void getStep() {
-          uint16_t p=analogRead(pin);
-          int a=p-center;
-          a=a>0?a:-a;
-          if (!(a>>inertia)) return;
-          float s=1000000.0/a/(sensivity+1);
-          long m=millis();
-          long dt=m-last;
-          if (abs(cnt)<=bufferSz&&dt>s) {
-            cnt+=p>center?1:-1;
-            last=m;
-          }
-          // MENU_DEBUG_OUT<<endl<<"dt:"<<dt<<" >s:"<<s;
-        }
-        inline navCmds pos() const {return inv^field_mode?negCmd:posCmd;}
-        inline navCmds neg() const {return inv^field_mode?posCmd:negCmd;}
-        int available(void) {getStep();return cnt!=0;}
-        int peek(void) override {
-          getStep();
-          if (cnt<0) return options->navCodes[neg()].ch;
-          if (cnt>0) return options->navCodes[pos()].ch;
-          return -1;
-        }
-        int read() override {
-          getStep();
-          if (cnt<0) {
-            cnt++;
-            return options->navCodes[neg()].ch;
-          }
-          if (cnt>0) {
-            cnt--;
-            return options->navCodes[pos()].ch;
-          }
-          return -1;
-        }
-        void flush() {cnt=0;last=millis();}
-        size_t write(uint8_t v) {cnt=v;return 1;}
-    };
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/ansiSerialOut.h b/src/menuIO/ansiSerialOut.h
deleted file mode 100644
index 216eae01..00000000
--- a/src/menuIO/ansiSerialOut.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Oct. 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-Use ANSI codes over serial output
-www.r-site.net
-
-***/
-#ifndef RSITE_ARDUINO_MENU_ANSISERIALOUT
-  #define RSITE_ARDUINO_MENU_ANSISERIALOUT
-  #include <AnsiStream.h>
-  #include "serialOut.h"
-
-  namespace Menu {
-
-    class ansiSerialOut:public serialOut {
-      public:
-        const colorDef<uint8_t> (&colors)[nColors];
-        inline ansiSerialOut(
-          Print& o,
-          const colorDef<uint8_t> (&c)[nColors],
-          idx_t* t,
-          panelsList& p
-        ) :serialOut(o,t,p,menuOut::minimalRedraw),colors(c) {}
-        inline uint8_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-          return memByte(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-        }
-        menuOut& fill(
-          int x1, int y1, int x2, int y2,char ch=' ',
-          colorDefs color=bgColor,
-          bool selected=false,
-          status stat=enabledStatus,
-          bool edit=false) override {
-            *this<<ANSI::setBackgroundColor(getColor(color,selected,stat,edit));
-            *this<<ANSI::fill(x1+1,y1+1,x2+1,y2+1,ch);
-            return *this;
-        }
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-          *this<<ANSI::xy(x+1+panels[panelNr].x,y+1+panels[panelNr].y);
-        }
-        void clear() override {
-          *this<<ANSI::xy(panels.maxX()+1,panels.maxY()+1)<<ANSI::eraseScreen()<<ANSI::xy(1,1);
-          panels.reset();
-        }
-        void clear(idx_t panelNr) override {
-          const panel p=panels[panelNr];
-          fill(p.x,p.y,p.x+p.w-1,p.y+p.h-1);
-          setCursor(0,0,panelNr);
-          panels.nodes[panelNr]=NULL;
-        }
-        void clearLine(
-          idx_t ln,
-          idx_t panelNr=0,
-          colorDefs color=bgColor,
-          bool selected=false,
-          status stat=enabledStatus,
-          bool edit=false
-        ) override {
-          const panel p=panels[panelNr];
-          *this<<ANSI::setBackgroundColor(getColor(color,selected,stat,edit));
-          *this<<ANSI::fill(p.x+1,ln+p.y+1,p.x+p.w,p.y+ln+1);
-        }
-        void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool e=false) override {
-          *this<<ANSI::setForegroundColor(getColor(c,selected,s,e));
-        }
-        virtual idx_t startCursor(bool charEdit) {
-          if (charEdit) *this<<ANSI::inverseOn();
-          else *this<<ANSI::boldOn();
-          return 0;
-        }
-        virtual idx_t endCursor(bool charEdit) {
-          if (charEdit) *this<<ANSI::inverseOff();
-          else *this<<ANSI::boldOff();
-          return 0;
-        }
-        virtual idx_t editCursor(idx_t x,idx_t y,bool editing,bool charEdit) {return 0;}
-    };
-
-  }//namespace Menu
-#endif
diff --git a/src/menuIO/chainStream.h b/src/menuIO/chainStream.h
deleted file mode 100644
index c7bc132b..00000000
--- a/src/menuIO/chainStream.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- C++ -*- */
-/***********
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-scan a chain of several input streams to provide input
-
-***/
-
-#ifndef RSITE_CHAINSTREAM_DEF_H
-  #define RSITE_CHAINSTREAM_DEF_H
-
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    template <int N>
-    class chainStream:public menuIn {
-      public:
-        static int on;
-        menuIn** streams;
-        chainStream<N>(menuIn** chain):streams(chain) {}
-        void setFieldMode(bool mode) override {
-          menuIn::setFieldMode(mode);
-          for(int n=0;n<N;n++) streams[n]->setFieldMode(mode);
-        }
-        int available(void) {
-          int cnt=0;
-          for(int n=0;n<N;n++)
-            cnt+=streams[n]->available();
-          return cnt;
-        }
-        int peek(void) {
-          for(int n=0;n<N;n++)
-            if (streams[n]->available()) return streams[n]->peek();
-          return -1;
-        }
-        int read() {
-          for(int n=0;n<N;n++) {
-            int key=streams[n]->available()?streams[n]->read():-1;
-            if (key!=on) {
-              on=-1;//key;
-              return key;
-            }
-              //streams[n]->read();
-              //if (key==-1) return -1;
-              //while(streams[n]->peek()==key) streams[n]->read();//wait for key release
-              //return key;
-          }
-          return -1;
-        }
-        void flush() {
-          for(int n=0;n<N;n++)
-            streams[n]->flush();
-        }
-        size_t write(uint8_t v) {return 0;}//this is readonly, ignoring
-    };
-
-    template<int N>
-    int chainStream<N>::on=-1;
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/clickEncoderIn.h b/src/menuIO/clickEncoderIn.h
deleted file mode 100644
index e5f0ef81..00000000
--- a/src/menuIO/clickEncoderIn.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- C++ -*- */
-/**************
-
-ClickEncoderStream.h
-
-Jun. 2016
-Modified by Christophe Persoz and Rui Azevedo.
-Based on keyStream.h developed by Rui Azevado.
-and ClickEncoder library by Peter Dannegger.
-https://github.com/christophepersoz/encoder
-
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-quick and dirty keyboard driver
-metaprog keyboard driver where N is the number of keys
-all keys are expected to be a pin (buttons)
-we can have reverse logic (pull-ups) by entering negative pin numbers
-ex: -A0 means: pin A0 normally high, low when button pushed (reverse logic)
-
-***/
-
-
-#ifndef __ClickEncoderStream_h__
-  #define __ClickEncoderStream_h__
-
-  #include <Arduino.h>
-
-  #ifndef ARDUINO_SAM_DUE
-    // Arduino specific libraries
-    // #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega328P__)
-      // #include <stdint.h>
-      //#include <avr/io.h>
-      //#include <avr/interrupt.h>
-      #include <ClickEncoder.h>
-    // #endif
-
-    #include "../menuDefs.h"
-
-    namespace Menu {
-
-      //emulate a stream based on clickEncoder movement returning +/- for every 'sensivity' steps
-      //buffer not needer because we have an accumulator
-    class ClickEncoderStream:public menuIn {
-      public:
-        ClickEncoder &enc; //associated hardware clickEncoder
-        int8_t sensivity;
-        int oldPos;
-        int pos;
-        ClickEncoder::Button btn;
-
-        inline void update() {
-          pos += enc.getValue();
-
-          if (btn == ClickEncoder::Open)//do not override previous input
-            btn = enc.getButton();
-        }
-
-        ClickEncoderStream(ClickEncoder &enc,int sensivity)
-          :enc(enc),
-          sensivity(sensivity),
-          oldPos(0),
-          pos(0),
-          btn(ClickEncoder::Open) {
-            pos = enc.getValue();
-          }
-
-
-        inline void setSensivity(int s) {
-            sensivity = s;
-        }
-
-        int available(void) {
-            return peek() != -1;
-        }
-
-        int peek(void) {
-          update();
-          if (btn == ClickEncoder::Clicked)
-            return options->navCodes[enterCmd].ch;//menu::enterCode;
-
-          if (btn == ClickEncoder::DoubleClicked)
-            return options->navCodes[escCmd].ch;//menu::escCode;
-
-          btn=ClickEncoder::Open;//2017, must consume not used input to proceed
-
-          int d = pos - oldPos;
-          if (d <= -sensivity)
-              return options->navCodes[downCmd].ch;//menu::downCode;
-          if (d >= sensivity)
-              return options->navCodes[upCmd].ch;//menu::upCode;
-          return -1;
-        }
-
-        int read()
-        {
-            int ch = peek();
-            btn = ClickEncoder::Open;
-            if (ch == options->navCodes[upCmd].ch)//menu::upCode)
-                oldPos += sensivity;
-            else if (ch == options->navCodes[downCmd].ch)//menu::downCode)
-                oldPos -= sensivity;
-            return ch;
-        }
-
-        void flush() {
-            btn=ClickEncoder::Open;//2017 clear current key
-            update();
-            oldPos = pos;
-        }
-
-        size_t write(uint8_t v) {
-            oldPos = v;
-            return 1;
-        }
-      };
-    }//namespace Menu
-
-  #endif
-
-#endif /* ClickEncoderStream_h */
diff --git a/src/menuIO/encoderIn.h b/src/menuIO/encoderIn.h
deleted file mode 100644
index 4e1c5a16..00000000
--- a/src/menuIO/encoderIn.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-quadrature encoder driver (PCINT)
-quadrature encoder stream (fake, not using buffers)
-
-*/
-
-#ifndef RSITE_ARDUINO_MENU_ENCODER
-  #define RSITE_ARDUINO_MENU_ENCODER
-
-  #include <pcint.h> //https://github.com/neu-rah/PCINT
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    template<uint8_t pinA,uint8_t pinB>
-    class encoderIn {
-    public:
-      volatile int pos=0;
-      //int pinA,pinB;
-      //encoderIn<pinA,pinB>(int a,int b):pinA(a),pinB(b) {}
-      void begin() {
-        pinMode(pinA, INPUT_PULLUP);
-        pinMode(pinB, INPUT_PULLUP);
-        //attach pin change handlers
-        PCattachInterrupt<pinA>(mixHandler((void(*)(void*))encoderInUpdateA,this), CHANGE);
-        PCattachInterrupt<pinB>(mixHandler((void(*)(void*))encoderInUpdateB,this), CHANGE);
-      }
-      //PCint handlers
-      static void encoderInUpdateA(class encoderIn<pinA,pinB> *e);
-      static void encoderInUpdateB(class encoderIn<pinA,pinB> *e);
-    };
-
-    //PCint handlers
-    template<uint8_t pinA,uint8_t pinB>
-    void encoderIn<pinA,pinB>::encoderInUpdateA(class encoderIn<pinA,pinB> *e) {
-      if (digitalRead(pinA)^digitalRead(pinB)) e->pos--;
-      else e->pos++;
-    }
-    template<uint8_t pinA,uint8_t pinB>
-    void encoderIn<pinA,pinB>::encoderInUpdateB(class encoderIn<pinA,pinB> *e) {
-      if (digitalRead(pinA)^digitalRead(pinB)) e->pos++;
-      else e->pos--;
-    }
-
-    //emulate a stream based on encoderIn movement returning +/- for every 'sensivity' steps
-    //buffer not needer because we have an accumulator
-    template<uint8_t pinA,uint8_t pinB>
-    class encoderInStream:public menuIn {
-    public:
-      encoderIn<pinA,pinB> &enc;//associated hardware encoderIn
-      int sensivity;
-      int oldPos=0;
-      encoderInStream(encoderIn<pinA,pinB> &enc,int sensivity):enc(enc), sensivity(sensivity) {}
-      inline void setSensivity(int s) {sensivity=s;}
-      int available(void) {return abs(enc.pos-oldPos)/sensivity;}
-      int peek(void) override {
-        int d=enc.pos-oldPos;
-        if (d<=-sensivity)return options->navCodes[downCmd].ch;
-        if (d>=sensivity) return options->navCodes[upCmd].ch;
-        return -1;
-      }
-      int read() override {
-        int d=enc.pos-oldPos;
-        if (d<=-sensivity) {
-          oldPos-=sensivity;
-          return options->navCodes[downCmd].ch;
-        }
-        if (d>=sensivity) {
-          oldPos+=sensivity;
-          return options->navCodes[upCmd].ch;
-        }
-        return -1;
-      }
-      void flush() {oldPos=enc.pos;}
-      size_t write(uint8_t v) {oldPos=v;return 1;}
-
-    };
-
-  }//namespace Menu
-#endif
diff --git a/src/menuIO/esp8266Out.cpp b/src/menuIO/esp8266Out.cpp
deleted file mode 100644
index 5bfe1c6c..00000000
--- a/src/menuIO/esp8266Out.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "../menuDefs.h"
-#ifdef MENU_FMT_WRAPS
-#include "esp8266Out.h"
-
-  menuOut& operator<<(menuOut&o,classes c) {
-    switch(c) {
-      case noClass:return o<<"noClass";break;
-      case promptClass:return o<<"prompt";break;
-      case fieldClass:return o<<"field";break;
-      case toggleClass:return o<<"toggle";break;
-      case selectClass:return o<<"select";break;
-      case chooseClass:return o<<"choose";break;
-      case valueClass:return o<<"value";break;
-      case menuClass:return o<<"menu";break;
-      default: return o;
-    }
-  }
-#endif
diff --git a/src/menuIO/esp8266Out.h b/src/menuIO/esp8266Out.h
deleted file mode 100644
index 8c66b69c..00000000
--- a/src/menuIO/esp8266Out.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* -*- C++ -*- */
-
-#ifndef RSITE_ARDUINO_MENU_ESP8266OUT
-  #define RSITE_ARDUINO_MENU_ESP8266OUT
-  #include "../menuDefs.h"
-  #include <ESP8266WiFi.h>
-  // based on WebServer:
-  //   https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer
-  //   https://github.com/Links2004/arduinoWebSockets
-  #include <WebSocketsServer.h>
-  #include <ESP8266WebServer.h>
-  #include <vector>
-  #include "xmlFmt.h"
-
-  using namespace std;
-
-  namespace Menu {
-
-    class esp8266Out:public webOut {
-      public:
-        esp8266Out(
-          idx_t* t,
-          panelsList& p,
-          menuOut::styles styles=(menuOut::styles)(redraw|expandEnums)
-        ):webOut(t,p,styles) {}
-        menuOut& fill(
-          int x1, int y1, int x2, int y2,char ch=' ',
-          colorDefs color=bgColor,
-          bool selected=false,
-          status stat=enabledStatus,
-          bool edit=false) override {return *this;}
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {}
-        void clear() override {panels.reset();}
-        void clear(idx_t panelNr) override {
-          setCursor(0,0,panelNr);
-          panels.nodes[panelNr]=NULL;
-        }
-        void clearLine(
-          idx_t ln,
-          idx_t panelNr=0,
-          colorDefs color=bgColor,
-          bool selected=false,
-          status stat=enabledStatus,
-          bool edit=false
-        ) override {}
-        void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool e=false) override {};
-        //template<typename T> esp8266Out& operator<<(T t)=0;
-    };
-
-    class esp8266BufferedOut:public esp8266Out {
-      public:
-        String response;
-        using esp8266Out::esp8266Out;
-        template<typename T> inline esp8266BufferedOut& operator<<(T t) {response<<t;return *this;}
-        size_t write(uint8_t ch) override {response+=(char)ch;return 1;}
-    };
-
-    menuOut& operator<<(menuOut&o,classes c);
-    template<typename T> inline String& operator<<(String& o,T t) {return o.operator+=(t);}
-
-    class esp8266_WebServerOut:public esp8266BufferedOut {
-      public:
-        ESP8266WebServer &server;
-        //using esp8266Out::esp8266Out;
-        esp8266_WebServerOut(
-          ESP8266WebServer &srv,
-          /*const colorDef<esp8266Out::webColor> (&c)[nColors],*/
-          idx_t* t,
-          panelsList& p
-        ):esp8266BufferedOut(t,p),server(srv) {}
-        size_t write(uint8_t ch) override {response<<(char)ch;return 1;}
-        // template<typename T> inline esp8266_WebServerOut& operator<<(T t) {response<<t;return *this;}
-    };
-
-    class esp8266_WebServerStreamOut:public esp8266Out {
-      public:
-        ESP8266WebServer &server;
-        inline esp8266_WebServerStreamOut(
-          ESP8266WebServer &srv,
-          idx_t* t,
-          panelsList& p
-        ):esp8266Out(t,p),server(srv) {}
-        inline size_t write(uint8_t ch) override {
-          char c[2]={ch,0};
-          server.sendContent(c);
-          return 1;
-        }
-        template<typename T> inline esp8266_WebServerStreamOut& operator<<(T t) {
-          server.sendContent(String()+t);
-          return *this;
-        }
-    };
-
-    // class esp8266_WebSocketOut:public esp8266BufferedOut {
-    //   public:
-    //     //client num... well we only serve a client at a time, so its safe to put t here
-    //     // of course this kind of code is not thead safe...but we dont have theads anyway
-    //     uint8_t num;
-    //     String response;
-    //     WebSocketsServer &webSocket;
-    //     esp8266_WebSocketOut(WebSocketsServer &socket,idx_t* tops,panelsList& panels)
-    //       :webSocket(socket),esp8266BufferedOut(tops,panels,(menuOut::styles)(minimalRedraw|expandEnums)) {}
-    //     size_t write(uint8_t ch) override {response<<(char)ch;return 1;}
-    // };
-
-    //template<typename T> inline esp8266_WebServerOut& operator<<(esp8266_WebServerOut&o , T t) {return o.operator<<(t);}
-    //template<typename T> inline esp8266_WiFiClientOut& operator<<(esp8266_WiFiClientOut&o , T t) {return o.operator<<(t);}
-    //template<typename T> inline esp8266Out& operator<<(esp8266Out&o , T t) {return o.operator<<(t);}
-
-  }//namespace Menu
-#endif
diff --git a/src/menuIO/htmlFmt.h b/src/menuIO/htmlFmt.h
deleted file mode 100644
index a044ce1e..00000000
--- a/src/menuIO/htmlFmt.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- C++ -*- */
-
-//this is a fossil, using xmlFmt instead
-
-#ifndef RSITE_ARDUINO_MENU_HTMLFMT
-  #define RSITE_ARDUINO_MENU_HTMLFMT
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    template<class T>
-    class htmlFmt:public T {
-      public:
-        using T::T;
-        result fmt(bool start,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) {
-          assert(idx>=0&&idx<nav.sz());
-          //prompt* n=&nav[idx];
-          switch(part) {
-            case menuOut::fmtPanel:
-              if (start)
-                *this
-                  <<"<div id=\""<<nav.target->hash()
-                  <<"\" class=\"aml_panel\">";
-              else T::operator<<("</div>");
-              break;
-            case menuOut::fmtTitle:
-              if (start) T::operator<<("<h2 class=\"aml_title\">");
-              else T::operator<<("</h2>");
-              break;
-            case menuOut::fmtBody:
-              if (start) T::operator<<("<ul class=\"aml_ops\">");
-              else T::operator<<("</ul>");
-              break;
-            case menuOut::fmtOp:
-              if (start) *this<<"<li class=\"aml_op\" data-idx=\""<<idx<<"\">";
-              else T::operator<<("</li>");
-              break;
-            case menuOut::fmtToggle:
-            case menuOut::fmtPrompt:
-              if (idx>=0&&(nav[idx].type()==promptClass||nav[idx].type()==toggleClass))
-                if (start) {
-                  *this<<"<a class=\"aml_link\" href=\"/menu?at=";
-                  nav.root->printPath(*this);
-                  *this<<"/"<<idx<<"\">";
-                } else *this<<"</a>";
-              break;
-            case menuOut::fmtSelect:
-            case menuOut::fmtChoose:
-              if(!start) break;
-              *this<<"<select data-path=\"/menu?at=";
-              nav.root->printPath(*this);
-              *this<<"/"<<idx<<"\">";
-              *this<<"\">";
-              for(idx_t n=0;n<((menuNode*)&nav[idx])->sz();n++)
-                *this
-                  <<"<option"<<(n==nav[idx].selected()?" selected":"")<<">"
-                  <<((menuNode*)&nav[idx])->operator[](n)<<"</option>";
-              *this<<"</select>";
-              return quit;
-              break;
-            case menuOut::fmtField:
-              if (start) {
-                *this<<"<input id=\""<<nav[idx].hash()<<"\" type=\"range\" data-idx=\""<<idx<<"\" min=\"";
-                nav[idx].printLow(*this);
-                *this<<"\" max=\"";
-                nav[idx].printHigh(*this);
-                *this<<"\" class=\"aml_field\" data-path=\"/menu?at=/"<<idx;
-                nav.root->printPath(*this);
-                *this<<"\" value=\"";
-              } else *this<<"\">";
-              break;
-            /*case menuOut::fmtIdx:break;
-            case menuOut::fmtCursor:break;
-            case menuOut::fmtOpBody:break;
-            case menuOut::fmtPreview:break;*/
-            default:break;
-          }
-          return proceed;
-        }
-        result fmtStart(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {return fmt(true,part,nav,idx);}
-        result fmtEnd(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {return fmt(false,part,nav,idx);}
-    };
-  }//namespace
-#endif
diff --git a/src/menuIO/interruptPins.h b/src/menuIO/interruptPins.h
deleted file mode 100644
index 85751f00..00000000
--- a/src/menuIO/interruptPins.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Oct. 2018 - modified for pin interrupts   Kevin O'Rourke
-
-quadrature encoder driver (PCINT) 
-quadrature encoder stream (fake, not using buffers)
-
-*/
-
-#ifndef RSITE_ARDUINO_MENU_ENCODER
-  #define RSITE_ARDUINO_MENU_ENCODER
-
-  #include <pcint.h> //https://github.com/neu-rah/PCINT
-  #include "../menuDefs.h"
-	
-  namespace Menu {
-
-    template<uint8_t pinUP,uint8_t pinDOWN,uint8_t pinSEL, uint8_t pinLEFT, uint8_t pinRIGHT>
-    class encoderIn {
-    public:
-      volatile int pos = 0;
-      volatile bool menu_running = false;
-      volatile bool menu_interrupt = false;
-      volatile unsigned long last_interrupt_time = 0;
-      void begin() {
-      	pinMode(pinUP, INPUT_PULLUP);
-	pinMode(pinDOWN, INPUT_PULLUP);
-	pinMode(pinSEL, INPUT_PULLUP);
-	pinMode(pinLEFT, INPUT_PULLUP);
-	pinMode(pinRIGHT, INPUT_PULLUP);
-	PCattachInterrupt<pinUP>(mixHandler((void(*)(void*))encoderInUpdateA,this), LOW);
-	PCattachInterrupt<pinDOWN>(mixHandler((void(*)(void*))encoderInUpdateB,this), LOW);
-	PCattachInterrupt<pinSEL>(mixHandler((void(*)(void*))encoderInUpdateC,this), LOW);
-	PCattachInterrupt<pinLEFT>(mixHandler((void(*)(void*))encoderInUpdateD,this), LOW);
-	PCattachInterrupt<pinRIGHT>(mixHandler((void(*)(void*))encoderInUpdateE,this), LOW);
-      }
-      static void encoderInUpdateA(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e);
-      static void encoderInUpdateB(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e);
-      static void encoderInUpdateC(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e);
-      static void encoderInUpdateD(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e);
-      static void encoderInUpdateE(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e);
-    };	
-	
-    //PCint handlers
-	
-    template<uint8_t pinUP,uint8_t pinDOWN,uint8_t pinSEL, uint8_t pinLEFT, uint8_t pinRIGHT>
-    void encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT>::encoderInUpdateA(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e) {
-       unsigned long interrupt_time = millis();
-       if (interrupt_time - e->last_interrupt_time > 20UL){
-		  if(e->menu_running){ 
-			e->menu_interrupt = true;
-			e->pos++;
-			}
-	    }
-		e->last_interrupt_time = interrupt_time;
-    }
-	
-    template<uint8_t pinUP,uint8_t pinDOWN,uint8_t pinSEL, uint8_t pinLEFT, uint8_t pinRIGHT>
-    void encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT>::encoderInUpdateB(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e) {
-       unsigned long interrupt_time = millis();
-       if (interrupt_time - e->last_interrupt_time > 20UL){
-		 if(e->menu_running){
-			e->menu_interrupt = true; 
-			e->pos--;
-			}
-	    }
-		e->last_interrupt_time = interrupt_time;
-    }
-	
-    template<uint8_t pinUP,uint8_t pinDOWN,uint8_t pinSEL, uint8_t pinLEFT, uint8_t pinRIGHT>
-    void encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT>::encoderInUpdateC(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e) {
-       unsigned long interrupt_time = millis();  
-	   if (interrupt_time - e->last_interrupt_time > 20UL){
-			if(e->menu_running){
-				e->pos+=2;
-			}else if(!e->menu_running) {
-				e->menu_running = true;//lock menu if false
-				}
-			e->menu_interrupt = true;				
-	    }
-		e->last_interrupt_time = interrupt_time;
-    }
-	
-    template<uint8_t pinUP,uint8_t pinDOWN,uint8_t pinSEL, uint8_t pinLEFT, uint8_t pinRIGHT>
-    void encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT>::encoderInUpdateD(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e) {
-       unsigned long interrupt_time = millis();
-       if (interrupt_time - e->last_interrupt_time > 20UL){
-		 if(e->menu_running){ 
-			e->menu_interrupt = true;
-			e->pos+=3;
-			}
-	    }
-		e->last_interrupt_time = interrupt_time;  
-    }
-	
-    template<uint8_t pinUP,uint8_t pinDOWN,uint8_t pinSEL, uint8_t pinLEFT, uint8_t pinRIGHT>
-    void encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT>::encoderInUpdateE(class encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> *e) {
-       unsigned long interrupt_time = millis();
-       if (interrupt_time - e->last_interrupt_time > 20UL){
-		  if(e->menu_running){
-			e->menu_interrupt = true;
-		    e->pos-=3;
-		    }
-	    }
-		e->last_interrupt_time = interrupt_time;  
-    }
-
-    //emulate a stream based on encoderIn movement returning +/- for every step
-    //buffer not needer because we have an accumulator
-    template<uint8_t pinUP,uint8_t pinDOWN,uint8_t pinSEL, uint8_t pinLEFT, uint8_t pinRIGHT>
-    class encoderInStream:public menuIn {
-    public:
-      encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> &enc;//associated hardware encoderIn
-      encoderInStream(encoderIn<pinUP,pinDOWN,pinSEL,pinLEFT,pinRIGHT> &enc):enc(enc) {}
-      int oldPos = 0;
-      int available(void) {return abs(enc.pos-oldPos);}
-      int peek(void) override {
-        int d = enc.pos-oldPos;
-        if (d==-1)return options->navCodes[downCmd].ch;
-        if (d==1) return options->navCodes[upCmd].ch;
-	if (d>=2) {
-		if (d>=3){
-			return options->navCodes[leftCmd].ch;
-		}else{
-			return options->navCodes[enterCmd].ch;
-			}
-        }
-	if (d<=-3){
-		return options->navCodes[rightCmd].ch;
-		}		
-        return -1;
-	}
-      int read() override {	
-        int d=enc.pos-oldPos;
-        if (d==-1) {
-          oldPos-=1;
-          return options->navCodes[downCmd].ch;
-        }
-        if (d==1) {
-          oldPos+=1;
-          return options->navCodes[upCmd].ch;
-        }		
-	if (d>=2) {
-		if (d>=3){
-			oldPos+=3;
-			return options->navCodes[leftCmd].ch;
-		}else{
-			oldPos+=2;
-			return options->navCodes[enterCmd].ch;
-			}
-        }
-	if (d<=-3){
-		oldPos-=3;
-		return options->navCodes[rightCmd].ch;
-		}
-        return -1;
-	}
-      void flush() {
-		  oldPos = enc.pos;
-		}
-      size_t write(uint8_t v) {
-		oldPos = v;
-		return 1;
-		}
-    };
-  }//namespace Menu
-#endif
-//void doNav(navCmd cmd);//fly by wire mode
diff --git a/src/menuIO/jsFmt.h b/src/menuIO/jsFmt.h
deleted file mode 100644
index 31b5d39b..00000000
--- a/src/menuIO/jsFmt.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- C++ -*- */
-#ifndef RSITE_ARDUINO_MENU_JSFMT
-  #define RSITE_ARDUINO_MENU_JSFMT
-  #include "../menuDefs.h"
-
-  //NOT A VALID FILE.. work in progress... maybe
-
-  namespace Menu {
-
-    template<class T>
-    class jsFmt:public T {
-      public:
-        using T::T;
-        result fmt(bool start,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) {
-          assert(idx>=0&&idx<nav.sz());
-          //prompt* n=&nav[idx];
-          switch(part) {
-            case menuOut::fmtSelect:
-            case menuOut::fmtChoose:
-              if(!start) break;
-              *this<<"menuReflex(\"";
-              nav.root->printPath(*this);
-              *this
-                <<"/"<<idx<<"\","
-                <<((menuVariant<int>*)&nav[idx])->reflex
-                <<");";
-              return quit;
-              break;
-            default:break;
-          }
-          return proceed;
-        }
-        result fmtStart(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {return fmt(true,part,nav,idx);}
-        result fmtEnd(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {return fmt(false,part,nav,idx);}
-    };
-  }//namespace
-#endif
diff --git a/src/menuIO/jsonFmt.cpp b/src/menuIO/jsonFmt.cpp
deleted file mode 100644
index 38165403..00000000
--- a/src/menuIO/jsonFmt.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "../menuDefs.h"
-#ifdef MENU_FMT_WRAPS
-  #include "jsonFmt.h"
-
-  namespace Menu {
-    #ifdef MENU_DEBUG
-      int partIndent=0;
-      const char* partName(menuOut::fmtParts part) {
-        switch (part){
-          case menuOut::fmtPanel: return "fmtPanel";
-          case menuOut::fmtTitle: return "fmtTitle";
-          case menuOut::fmtBody: return "fmtBody";
-          case menuOut::fmtOp: return "fmtOp";
-          case menuOut::fmtIdx: return "fmtIdx";
-          case menuOut::fmtCursor: return "fmtCursor";
-          case menuOut::fmtOpBody: return "fmtOpBody";
-          case menuOut::fmtPreview: return "fmtPreview";
-          case menuOut::fmtPrompt: return "fmtPrompt";
-          case menuOut::fmtField: return "fmtField";
-          case menuOut::fmtToggle: return "fmtToggle";
-          case menuOut::fmtSelect: return "fmtSelect";
-          case menuOut::fmtChoose: return "fmtChoose";
-          case menuOut::fmtUnit: return "fmtUnit";
-          case menuOut::fmtTextField: return "fmtTextField";
-          case menuOut::fmtCursorOpen: return "fmtCursorOpen";
-          case menuOut::fmtCursorClose: return "fmtCursorClose";
-          case menuOut::fmtValue: return "fmtVluea";
-          default: return "???";
-        }
-      }
-      void printIndent() {
-        for(int n=0;n<partIndent;n++) MENU_DEBUG_OUT<<"  ";
-      }
-    #endif
-    int cursorCtrl=0;
-    void jsonOptions(menuOut& o,navNode &nav,menuNode& node,idx_t idx) {
-      o<<",\"options\":[";
-      // o<<node.sz();
-      for(idx_t n=0;n<node.sz();n++)
-        o<<(n?",":"")<<"\""<<node[n]<<"\"";
-      o<<"],\"sel\":\""<<((menuVariantBase*)&node)->sync()<<"\"";
-    }
-  };
-#endif
diff --git a/src/menuIO/jsonFmt.h b/src/menuIO/jsonFmt.h
deleted file mode 100644
index 1c7faa3d..00000000
--- a/src/menuIO/jsonFmt.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- C++ -*- */
-
-#ifndef RSITE_ARDUINO_MENU_JSONFMT
-  #define RSITE_ARDUINO_MENU_JSONFMT
-
-  #ifdef MENU_FMT_WRAPS
-    #include "../menuDefs.h"
-    #include "../items.h"
-    #include "esp8266Out.h"
-
-    namespace Menu {
-
-      #ifdef MENU_DEBUG
-        extern int partIndent;
-        const char* partName(menuOut::fmtParts part);
-        void printIndent();
-      #endif
-
-      extern int cursorCtrl;
-
-      void jsonOptions(menuOut& o,navNode &nav,menuNode& node,idx_t idx);
-
-      //wraps a webserver output and writes xml to it
-      template<class T>
-      class jsonFmt:public T {
-        public:
-          using T::T;
-          result fmt(bool start,prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) {
-            switch(part) {
-              case menuOut::fmtPanel:
-                if (start) *this<<"{";
-                else T::operator<<("}");
-                break;
-              case menuOut::fmtTitle:
-                if (start) T::operator<<("\"title\":{");
-                else T::operator<<("}\n");
-                break;
-              case menuOut::fmtBody:
-                if (start) {
-                  *this<<",\"path\":\"";
-                  nav.root->printPath(*this,(menuNode*)&target);
-                  *this<<"\",\"sel\":\""<<nav.sel<<"\"";
-                  *this<<",\"items\":[\n";
-                } else T::operator<<("\n]\n");
-                break;
-              case menuOut::fmtUnit:
-                *this<<(start?",\"unit\":\"":"\"");
-                break;
-              case menuOut::fmtOp:
-                if (start) {
-                  if (idx>0) *this<<",\n";
-                  *this<<"{\"idx\":\""<<idx<<"\""
-                    <<",\"enabled\":\""<<target.enabled<<"\"";
-                } else *this<<("}");
-                break;
-              case menuOut::fmtToggle:
-                if (start) {
-                  *this<<",\"value\":\"";
-                } else {
-                  *this<<"\"";
-                  jsonOptions(*this,nav,*(menuNode*)&target,idx);
-                  // *this<<",";
-                }
-                break;
-              case menuOut::fmtPrompt:
-                if (start) {
-                  if (idx>=0) *this<<",";
-                  *this<<"\"prompt\":\"";
-                } else {
-                  *this<<"\"";
-                  if (target.has(_asPad))
-                    *this<<",\"pad\":[";
-                };
-                break;
-              case menuOut::fmtValue:
-                if (start) *this<<",\"value\":\"";
-                else *this<<"\"";
-                break;
-              case menuOut::fmtSelect:
-                if (start) {
-                  *this<<",\"select\":\"";
-                } else {
-                  *this<<"\"";
-                  jsonOptions(*this,nav,*(menuNode*)&target,idx);
-                }
-                break;
-              case menuOut::fmtChoose:
-                if (start) {
-                  *this<<",\"choose\":\"";
-                } else {
-                  *this<<"\"";
-                  jsonOptions(*this,nav,*(menuNode*)&target,idx);
-                }
-                break;
-                break;
-              case menuOut::fmtField:
-                if (start) {
-                  *this<<",\"field\":\"";
-                } else {
-                  *this<<"\",\"range\":{\"low\":\"";
-                  target.printLow(*this);
-                  *this<<"\",\"high\":\"";
-                  target.printHigh(*this);
-                  *this<<"\",\"step\":\"";
-                  target.printStep(*this);
-                  *this<<"\",\"tune\":\"";
-                  target.printTune(*this);
-                  *this<<"\"}";
-                }
-                break;
-              case menuOut::fmtEditCursor:
-                if (start) *this<<",\"editCursor\":\"";
-                else *this<<"\"";
-                break;
-              case menuOut::fmtTextField:
-                if (start) *this<<",\"text\":\"";
-                else *this<<"\"";
-                break;
-              case menuOut::fmtIdx:
-                // if (start) *this<<"\"idx\":";
-                // else *this<<",";
-                break;
-              case menuOut::fmtCursor:
-                if (start) *this<<",\"cursor\":\"";
-                else *this<<"\"";
-                break;
-              case menuOut::fmtCursorOpen:
-                if (start) *this<<",\"selStart\":\"";
-                else *this<<"\"";
-                break;
-              case menuOut::fmtCursorClose:
-                if (start) *this<<",\"selEnd\":\"";
-                else *this<<"\"";
-                break;
-              case menuOut::fmtOpBody:
-                if (start) {
-                  // *this<<"\"body\":{";
-                  // if (target.has(_asPad)) *this<<"\"pad\":[";
-                } else {
-                  if (target.has(_asPad)) *this<<"]";
-                  // *this<<"}";
-                }
-                break;
-              case menuOut::fmtPreview:
-                if (start) *this<<",\"preview\":\"";
-                else *this<<"\"\n";
-                break;
-              default:break;
-            }
-            return proceed;
-          }
-          result fmtStart(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {
-            trace(printIndent();MENU_DEBUG_OUT<<">"<<partName(part)<<" "<<idx<<" "<<target<<endl);
-            #ifdef MENU_DEBUG
-              partIndent++;
-            #endif
-            return fmt(true,target,part,nav,idx);
-          }
-          result fmtEnd(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {
-            #ifdef MENU_DEBUG
-              partIndent--;
-            #endif
-            trace(printIndent();MENU_DEBUG_OUT<<"<"<<partName(part)<<endl);
-            return fmt(false,target,part,nav,idx);
-          }
-      };
-    }//namespace
-  #endif
-#endif
diff --git a/src/menuIO/keyIn.h b/src/menuIO/keyIn.h
deleted file mode 100644
index c253e695..00000000
--- a/src/menuIO/keyIn.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- C++ -*- */
-/**************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-quick and dirty keyboard driver
-metaprog keyboard driver where N is the number of keys
-all keys are expected to be a pin (buttons)
-we can have reverse logic (pull-ups) by entering negative pin numbers
-ex: -A0 means: pin A0 normally high, low when button pushed (reverse logic)
-
-***/
-
-#ifndef RSITE_KEYIN_DEF_H
-  #define RSITE_KEYIN_DEF_H
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    #include "keyMapDef.h"
-
-    //if you hold/repeat a key for this ammount of time we will consider it an escape
-    #ifndef ESCAPE_TIME
-    #define ESCAPE_TIME 1500
-    #endif
-    //emulate a stream keyboard, this is not using interrupts as a good driver should do
-    // AND is not using a buffer either!
-    template <int N>
-    class keyIn:public menuIn {
-    public:
-      keyMap* keys;
-      int lastkey;
-      unsigned long pressMills=0;
-      keyIn<N>(keyMap k[]):keys(k),lastkey(-1) {}
-      void begin() {
-        for(int n=0;n<N;n++)
-          if (keys[n].pin<0) pinMode(-keys[n].pin,INPUT_PULLUP);
-          else pinMode(keys[n].pin,INPUT);
-      }
-      int available(void) {
-        //MENU_DEBUG_OUT<<"available"<<endl;
-        int ch=peek();
-        if (lastkey==-1) {
-          lastkey=ch;
-          pressMills=millis();
-        } else if (ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME) return 1;
-        if (ch==lastkey) return 0;
-        return 1;
-        /*int cnt=0;
-        for(int n=0;n<N;n++) {
-          int8_t pin=keys[n].pin;
-          if (digitalRead(pin<0?-pin:pin)!=(pin<0) ) cnt++;
-        }
-        return cnt;*/
-      }
-      int peek(void) {
-        //MENU_DEBUG_OUT<<"peek"<<endl;
-        for(int n=0;n<N;n++) {
-          int8_t pin=keys[n].pin;
-          if (digitalRead(pin<0?-pin:pin)!=(pin<0) ) return keys[n].code;
-        }
-        return -1;
-      }
-      int read() {
-        //MENU_DEBUG_OUT<<"read"<<endl;
-        int ch=peek();
-        if (ch==lastkey) return -1;
-        int tmp=lastkey;
-        bool longPress=ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME;
-        //MENU_DEBUG_OUT<<"read lastkey="<<lastkey<<" ch="<<ch<<endl;
-        //MENU_DEBUG_OUT<<"down time:"<<millis()-pressMills<<endl;
-        pressMills=millis();
-        lastkey=ch;
-        return longPress?options->getCmdChar(escCmd):tmp;//long press will result in escape
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/keyMapDef.h b/src/menuIO/keyMapDef.h
deleted file mode 100644
index 10a9035a..00000000
--- a/src/menuIO/keyMapDef.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* -*- C++ -*- */
-
-#ifndef RSITE_ARDUINO_MENU_KEYMAP
-  #define RSITE_ARDUINO_MENU_KEYMAP
-
-struct keyMap {
-  int8_t pin;
-  int8_t code;
-};
-
-#endif
diff --git a/src/menuIO/keypadIn.h b/src/menuIO/keypadIn.h
deleted file mode 100644
index a5edf00f..00000000
--- a/src/menuIO/keypadIn.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- C++ -*- */
-/**************
-Jan. 2018 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-keypad driver
-using
-  http://playground.arduino.cc/Code/Keypad
-  https://github.com/Nullkraft/Keypad
-
-***/
-
-#ifndef RSITE_KEYPAD_DEF_H
-  #define RSITE_KEYPAD_DEF_H
-  #include "../menuDefs.h"
-
-  #include <Keypad.h>
-  namespace Menu {
-
-    class keypadIn:public menuIn {
-    public:
-      char key=0;
-      Keypad& in;
-      keypadIn(Keypad& in):in(in) {}
-      int available(void) {return peek()!=-1;}
-      int peek(void) {return key?key:(key=in.getKey())?key:-1;}
-      int read() {
-        if (key) {
-          char k=key;
-          key=0;
-          return k;
-        }
-        return available()?read():-1;
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-  };
-#endif
diff --git a/src/menuIO/lcdOut.h b/src/menuIO/lcdOut.h
deleted file mode 100644
index af599b44..00000000
--- a/src/menuIO/lcdOut.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- C++ -*- */
-
-//for using F. Malpartida LCD's driver
-//https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
-
-#ifndef RSITE_ARDUINO_MENU_LCDOUT
-  #define RSITE_ARDUINO_MENU_LCDOUT
-
-  #ifndef ARDUINO_SAM_DUE
-    #include "../menuDefs.h"
-    #include <Wire.h>
-    #include <LCD.h>
-
-    namespace Menu {
-
-      class lcdOut:public cursorOut {
-        public:
-          LCD* device;
-          inline lcdOut(LCD* o,idx_t *t,panelsList &p,menuOut::styles s=menuOut::minimalRedraw)
-            :cursorOut(t,p,s),device(o) {}
-          size_t write(uint8_t ch) override {return device->write(ch);}
-          void clear() override {
-            device->clear();
-            panels.reset();
-          }
-          void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-            const panel p=panels[panelNr];
-            device->setCursor(p.x+x,p.y+y);
-          }
-          idx_t startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0) override {return 0;}
-          idx_t endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0) override {return 0;}
-          idx_t editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr=0) override {
-            trace(MENU_DEBUG_OUT<<"lcdOut::editCursor "<<x<<","<<y<<endl);
-            //text editor cursor
-            device->noBlink();
-            device->noCursor();
-            if (editing) {
-              device->setCursor(x, y);
-              if (charEdit) device->cursor();
-              else device->blink();
-            }
-            return 0;
-          }
-
-      };
-
-    }//namespace Menu
-
-  #endif
-#endif
diff --git a/src/menuIO/liquidCrystalOut.h b/src/menuIO/liquidCrystalOut.h
deleted file mode 100644
index ce95e4e5..00000000
--- a/src/menuIO/liquidCrystalOut.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- C++ -*- */
-
-//for using standard arduino LiquidCrystal driver
-
-#ifndef RSITE_ARDUINO_MENU_LIQUIDCRYSTALOUT
-  #define RSITE_ARDUINO_MENU_LIQUIDCRYSTALOUT
-  #include "../menuDefs.h"
-  #include <LiquidCrystal.h>
-
-  namespace Menu {
-
-    class liquidCrystalOut:public cursorOut {
-      public:
-        LiquidCrystal& device;
-        inline liquidCrystalOut(LiquidCrystal& o,idx_t *t,panelsList &p,menuOut::styles s=minimalRedraw)
-          :cursorOut(t,p,s),device(o) {}
-        size_t write(uint8_t ch) override {return device.write(ch);}
-        void clear() override {
-          device.clear();
-          panels.reset();
-        }
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-          const panel p=panels[panelNr];
-          device.setCursor(p.x+x,p.y+y);
-        }
-        idx_t startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0) override {return 0;}
-        idx_t endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0) override {return 0;}
-        idx_t editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr=0) override {
-          //text editor cursor
-          device.noBlink();
-          device.noCursor();
-          if (editing) {
-            device.setCursor(x, y);
-            if (charEdit) device.cursor();
-            else device.blink();
-          }
-          return 0;
-        }
-    };
-
-  }//namespace Menu
-#endif
diff --git a/src/menuIO/serialIn.h b/src/menuIO/serialIn.h
deleted file mode 100644
index f80414d3..00000000
--- a/src/menuIO/serialIn.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Sept 2014 ~ Sept. 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-www.r-site.net
-
-HardwareSerial input driver
-***/
-
-#ifndef RSITE_ARDUINO_MENU_HW_SERIALIN
-  #define RSITE_ARDUINO_MENU_HW_SERIALIN
-  #include "../menuDefs.h"
-
-  #define SERIAL_CLASS Stream
-
-  namespace Menu {
-    class serialIn:public menuIn {
-      public:
-        Stream& in;
-        serialIn(Stream& serial):in(serial) {}
-        size_t write(uint8_t o) override {return in.write(o);}
-        int available() override {return in.available();}
-        int peek() override {return in.peek();}
-        int read() override {return in.read();}
-        void flush() override {in.flush();}
-    };
-
-  }
-
-#endif
diff --git a/src/menuIO/serialOut.cpp b/src/menuIO/serialOut.cpp
deleted file mode 100644
index c0199fd8..00000000
--- a/src/menuIO/serialOut.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#include "serialOut.h"
-
-namespace Menu {
-  constMEM panel default_serial_panels[] MEMMODE={{0,0,40,10}};
-  navNode* default_serial_nodes[sizeof(default_serial_panels)/sizeof(panel)];
-  panelsList default_serial_panel_list(
-    default_serial_panels,
-    default_serial_nodes,
-    sizeof(default_serial_panels)/sizeof(panel)
-  );
-};
diff --git a/src/menuIO/serialOut.h b/src/menuIO/serialOut.h
deleted file mode 100644
index 929a516a..00000000
--- a/src/menuIO/serialOut.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- C++ -*- */
-
-#ifndef RSITE_ARDUINO_MENU_SERIALOUT
-  #define RSITE_ARDUINO_MENU_SERIALOUT
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    extern panelsList default_serial_panel_list;
-
-    class serialOut:public menuOut {
-      public:
-        Print& device;
-        idx_t lastLine=-1;
-        inline serialOut(Print& o,idx_t* t,panelsList &p=default_serial_panel_list,menuOut::styles st=menuOut::none)
-          :menuOut(t,p,(menuOut::styles)(st|menuOut::drawNumIndex)),device(o) {}
-        size_t write(uint8_t ch) override {
-          //trace(MENU_DEBUG_OUT.write('|'));
-          return device.write(ch);
-        }
-        void clear() override {
-          println();
-          panels.reset();
-        }
-        void clear(idx_t panelNr) override {
-          trace(MENU_DEBUG_OUT<<"serialOut::clear(idx_t panelNr)"<<endl;)
-          trace(MENU_DEBUG_OUT.flush());
-          println();
-          panels.nodes[panelNr]=NULL;
-        }
-        void clearLine(
-          idx_t ln,
-          idx_t panelNr=0,
-          colorDefs color=bgColor,
-          bool selected=false,
-          status stat=enabledStatus,
-          bool edit=false
-        ) override {
-          lastLine=-1;
-          device.println();
-        }
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-          if (lastLine>=0&&lastLine!=y) println();
-          lastLine=y;
-        };
-    };
-
-  }//namespace Menu
-
-
-#endif
diff --git a/src/menuIO/softKeyIn.h b/src/menuIO/softKeyIn.h
deleted file mode 100644
index 0e3d3faa..00000000
--- a/src/menuIO/softKeyIn.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- C++ -*- */
-
-/**************
-Sept. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-Oct. 2016 - dontsovcmc (https://github.com/dontsovcmc) added debounce safe
-  https://github.com/neu-rah/ArduinoMenu/pull/60
-
-quick and dirty keyboard driver
-metaprog keyboard driver where N is the number of keys
-all keys are expected to be a pin (buttons)
-we can have reverse logic (pull-ups) by entering negative pin numbers
-ex: -A0 means: pin A0 normally high, low when button pushed (reverse logic)
-***/
-
-#ifndef __softKeyIn_h__
-  #define __softKeyIn_h__
-
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    #include "keyMapDef.h"
-
-    #ifndef BOUNCE_TICK
-    #define BOUNCE_TICK 30
-    #endif
-
-    //if you hold/repeat a key for this ammount of time we will consider it an escape
-    #ifndef ESCAPE_TIME
-    #define ESCAPE_TIME 1500
-    #endif
-    //emulate a stream keyboard, this is not using interrupts as a good driver should do
-    // AND is not using a buffer either!
-    template <int N>
-    class softKeyIn:public menuIn {
-    public:
-      keyMap* keys;
-      int lastkey;
-      unsigned long pressMills=0;
-      softKeyIn<N>(keyMap k[]):keys(k),lastkey(-1) {}
-      int available(void) {
-        int ch=peek();
-        if (lastkey==-1) {
-          lastkey=ch;
-          pressMills=millis();
-        }
-    	else if (ch == -1 && millis()-pressMills < BOUNCE_TICK)
-    	{
-    		lastkey = -1;  //released = it's bounce. reset lastkey
-        return 0;
-    	}
-    	else if (ch != -1 && millis()-pressMills > BOUNCE_TICK) return 1;
-    	else if (ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME) return 1;
-
-        if (ch==lastkey) return 0;
-
-        return 1;
-        /*int cnt=0;
-        for(int n=0;n<N;n++) {
-          int8_t pin=keys[n].pin;
-          if (digitalRead(pin<0?-pin:pin)!=(pin<0) ) cnt++;
-        }
-        return cnt;*/
-      }
-      int peek(void) {
-        //MENU_DEBUG_OUT<<"peek"<<endl;
-        for(int n=0;n<N;n++) {
-          int8_t pin=keys[n].pin;
-          if (digitalRead(pin<0?-pin:pin)!=(pin<0) ) return keys[n].code;
-        }
-        return -1;
-      }
-      int read() {
-        //MENU_DEBUG_OUT<<"read"<<endl;
-        int ch=peek();
-        if (ch==lastkey) return -1;
-        int tmp=lastkey;
-        bool longPress=ESCAPE_TIME&&millis()-pressMills>ESCAPE_TIME;
-        //MENU_DEBUG_OUT<<"read lastkey="<<lastkey<<" ch="<<ch<<endl;
-        //MENU_DEBUG_OUT<<"down time:"<<millis()-pressMills<<endl;
-        pressMills=millis();
-        lastkey=ch;
-        return longPress?options->getCmdChar(escCmd):tmp;//long press will result in escape
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/stringIn.h b/src/menuIO/stringIn.h
deleted file mode 100644
index 16913ce6..00000000
--- a/src/menuIO/stringIn.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Feb.2018 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-www.r-site.net
-
-string input driver
-***/
-
-#ifndef RSITE_ARDUINO_MENU_HW_STRINGIN
-  #define RSITE_ARDUINO_MENU_HW_STRINGIN
-  #include "../menuDefs.h"
-
-  namespace Menu {
-    //using a circular buffer
-    //attention, if using sz=0 (2^0=1) we just override previous character
-    template<uint8_t sz=0>//this size is 2^sz
-    class stringIn:public menuIn {
-      public:
-        static_assert(sz<7,"ArduinoMenu: max buffer size is 2^7");
-        enum Mask:uint8_t {
-          nBytes=1<<sz,
-          mask=nBytes-1
-        };
-        char data[nBytes]={0};
-        uint8_t head=0;
-        uint8_t at=0;
-        size_t write(uint8_t o) override {
-          if (sz&&(at==mask&(head-1))) return 0;//buffer full!
-          data[at]=o;
-          at++;
-          at&=mask;
-          return 1;
-        }
-        int available() override {return sz?at-head:data[head]!=0;}
-        int peek() override {return available()?data[head]:0;}
-        int read() override {
-          if (available()) {
-            if (sz&&(head==at)) return -1;
-            int r=data[head];
-            if(!sz) data[head]=0;
-            head++;
-            head&=mask;
-            return r;
-          }
-          return -1;
-        }
-        void flush() override {at=head=0;}//just throw away all data!
-    };
-  }
-
-#endif
diff --git a/src/menuIO/tftOut.h b/src/menuIO/tftOut.h
deleted file mode 100644
index a7fd63b0..00000000
--- a/src/menuIO/tftOut.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- C++ -*- */
-/********************
-Sept. 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-Use Arduino TFT as menu output
-www.r-site.net
-
-***/
-#ifndef RSITE_ARDUINOP_MENU_TFT
-	#define RSITE_ARDUINOP_MENU_TFT
-	#include <TFT.h>
-	#include "../menuDefs.h"
-
-namespace Menu {
-
-		#define RGB565(r,g,b) ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)))
-
-	  class TFTOut:public gfxOut {
-	    public:
-				Adafruit_GFX& gfx;
-				const colorDef<uint16_t> (&colors)[nColors];
-		    TFTOut(Adafruit_GFX& gfx,const colorDef<uint16_t> (&c)[nColors],idx_t* t,panelsList &p,idx_t resX=6,idx_t resY=9)
-					:gfxOut(resX,resY,t,p),gfx(gfx),colors(c) {}
-					//:gfxOut(gfx.width()/resX,gfx.height()/resY,resX,resY,false),colors(c),gfx(gfx) {}
-
-				size_t write(uint8_t ch) override {return gfx.write(ch);}
-
-				inline uint16_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-          return memWord(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-        }
-
-				void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool e=false) override {
-					gfx.setTextColor(getColor(c,selected,s,e));
-				}
-
-				void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,(p.y+ln)*resY,p.maxX()*resX,resY,getColor(color,selected,stat,edit));
-		    	//setCursor(0,ln);
-		    }
-		    void clear() override {
-					panels.reset();
-					gfx.fillScreen(getColor(bgColor,false,enabledStatus,false));
-		    	setCursor(0,0);
-					setColor(fgColor);
-				}
-
-				void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.drawRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY,getColor(c,selected,stat,edit));
-				}
-
-				void clear(idx_t panelNr) override {
-					const panel p=panels[panelNr];
-					gfx.fillRect(p.x*resX,p.y*resY,p.w*resX,p.h*resY,getColor(bgColor,false,enabledStatus,false));
-					panels.nodes[panelNr]=NULL;
-				}
-
-		    void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					gfx.setCursor((p.x+x)*resX,(p.y+y)*resY+fontMarginY);
-				}
-
-				void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					// gfxOut::drawCursor(ln,selected,stat);
-					gfx.drawRect(p.x*resX,(p.y+ln)*resY,maxX()*resX,resY,getColor(cursorColor,selected,enabledStatus,false));
-				}
-	  };
-
-}; //namespace adaGfxOut
-#endif
diff --git a/src/menuIO/u8g2Out.h b/src/menuIO/u8g2Out.h
deleted file mode 100644
index 72ea64e7..00000000
--- a/src/menuIO/u8g2Out.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- C++ -*- */
-
-/********************
-Oct. 2016 Stephen Denne https://github.com/datacute
-Based on U8GLibOut.h from Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Original from: https://github.com/christophepersoz
-
-Use graphics screens as menu output, based on U8G2 graphic display
-www.r-site.net
-
-***/
-#ifndef RSITE_ARDUINOP_MENU_U8G2
-#define RSITE_ARDUINOP_MENU_U8G2
-#include <U8g2lib.h>
-#include "menuDefs.h"
-
-namespace Menu {
-
-	class u8g2Out:public gfxOut {
-		public:
-      int8_t offsetX=0;
-      int8_t offsetY=0;
-			U8G2& gfx;
-			const colorDef<uint8_t> (&colors)[nColors];
-			u8g2Out(
-				U8G2& gfx,
-				const colorDef<uint8_t> (&c)[nColors],
-				idx_t* t,
-				panelsList &p,
-				idx_t resX=6,
-				idx_t resY=9,
-				idx_t offsetX=0,
-				idx_t offsetY=0,
-        int fontMarginY=1
-			) :gfxOut(resX,resY,t,p,(styles)(menuOut::redraw|menuOut::rasterDraw)),gfx(gfx),colors(c) {
-					gfx.setFontPosBottom(); // U8Glib font positioning
-					this->offsetX=offsetX;
-					this->offsetY=offsetY;
-          this->fontMarginY=fontMarginY;
-			}
-
-			u8g2Out(
-				U8G2& gfx,
-				const colorDef<uint8_t> (&c)[nColors],
-				idx_t* t,
-				panelsList &p,
-				idx_t resX,
-				idx_t resY,
-				idx_t offsetX,
-				idx_t offsetY,
-				int fontMarginX,
-				int fontMarginY
-			) :gfxOut(resX,resY,t,p,(styles)(menuOut::redraw|menuOut::rasterDraw)),gfx(gfx),colors(c) {
-					gfx.setFontPosBottom(); // U8Glib font positioning
-					this->offsetX=offsetX;
-					this->offsetY=offsetY;
-					this->fontMarginX=fontMarginX;
-					this->fontMarginY=fontMarginY;
-			}
-
-			size_t write(uint8_t ch) override {return gfx.write(ch);}
-
-			inline uint8_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-				return memByte(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-			}
-
-			void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool edit=false) override {
-				gfx.setDrawColor(getColor(c,selected,s,edit));
-			}
-
-			void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-				const panel p=panels[panelNr];
-				setColor(color,selected,stat,edit);
-				gfx.drawBox(p.x*resX + offsetX - 1,(p.y+ln)*resY + offsetY /*- fontMarginY*/,maxX()*resX /*+ fontMarginY*/ /*+ fontMarginY*/,resY /*+ fontMarginY*/ /*+ fontMarginY*/);
-				//setCursor(0,ln);
-			}
-			void clear() override {
-				setCursor(0,0);
-				setColor(fgColor);
-				panels.reset();
-			}
-			void clear(idx_t panelNr) override {
-				const panel p=panels[panelNr];
-				setColor(bgColor,false,enabledStatus,false);
-				gfx.drawBox(p.x*resX + offsetX,p.y*resY + offsetY,p.w*resX,p.h*resY);
-				//clear();
-				panels.nodes[panelNr]=NULL;
-			}
-			void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-				const panel p=panels[panelNr];
-				gfx.drawFrame((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY/*+(fontMarginY<<1)*/);
-			}
-
-			void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-				const panel p=panels[panelNr];
-				gfx.drawBox((p.x+x)*resX,(p.y+y)*resY,w*resX,h*resY/*+(fontMarginY<<1)*/);
-			}
-
-			void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-				// _trace(Serial<<"setCursor"<<endl);
-				const panel p=panels[panelNr];
-				gfx.tx = (p.x+x)*resX+fontMarginX + offsetX;
-				gfx.ty = (p.y+y+1)*resY-fontMarginY + offsetY;
-			}
-
-			idx_t startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) override {
-			  if (charEdit) {
-			    // rect(panelNr,  x-1,  y, 1, 1, bgColor, false, enabledStatus, false);
-					const panel p=panels[panelNr];
-					gfx.drawBox((p.x+x)*resX + offsetX +fontMarginX,(p.y+y)*resY+ offsetY /*-fontMarginY*/,resX,resY);
-			    setColor(fgColor,false,enabledStatus,false);
-			  }/* else
-			    box(panelNr,  x,  y, 1, 1, bgColor, false, enabledStatus, false);*/
-			  return 0;
-			}
-
-			// idx_t endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) override {
-			//   setColor(fgColor,true,enabledStatus,true);return 0;
-			// }
-
-      idx_t editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr=0) override {
-			  if (editing) {
-					_trace(Serial<<"editCursor"<<endl);
-					// box(panelNr,x-1,y);
-					const panel p=panels[panelNr];
-					gfx.drawFrame((x+p.x-1)*resX + offsetX + fontMarginX-1,(p.y+y)*resY + offsetY /*- fontMarginY+2*/,resX+1 ,resY);
-				}
-			  return 0;
-			}
-
-			void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-				// _trace(Serial<<"drawCursor"<<endl);
-				const panel p=panels[panelNr];
-				// gfxOut::drawCursor(ln,selected,stat);
-				setColor(cursorColor,selected,stat);
-				gfx.drawFrame(p.x*resX + offsetX /*+ fontMarginX*/,(p.y+ln)*resY + offsetY /*+ fontMarginY*/,maxX()*resX ,resY);
-			}
-			idx_t printRaw(const char* at,idx_t len) override {
-				trace(Serial<<"u8g2Out::printRaw"<<endl);
-				trace(Serial<<"["<<at<<"]");
-				return print((__FlashStringHelper*)at);
-			  // const char* p=at;
-			  // uint8_t ch;
-			  // for(int n=0;(ch=memByte(at++))&&(len==0||n<len);n++) {
-				// 	trace(Serial<<"["<<ch<<"]");
-			  //   write(ch);
-			  // }
-			  // return at-p-1;
-			}
-
-	};
-}
-#endif //RSITE_ARDUINOP_MENU_U8G2
diff --git a/src/menuIO/uartOut.h b/src/menuIO/uartOut.h
deleted file mode 100644
index eccf0525..00000000
--- a/src/menuIO/uartOut.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- C++ -*- */
-
-/********************
-Oct. 2016 Stephen Denne https://github.com/datacute
-Based on U8GLibOut.h from Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-Original from: https://github.com/christophepersoz
-
-Use graphics screens as menu output, based on U8G2 graphic display
-www.r-site.net
-
-***/
-#ifndef RSITE_ARDUINOP_MENU_UART
-#define RSITE_ARDUINOP_MENU_UART
-#include "menuDefs.h"
-
-namespace Menu {
-
-class uartOut:public gfxOut {
-	public:
-		enum systemFont {
-			font16 = 16,
-			font24 = 24,
-			font32 = 32
-		};
-		int8_t offsetX=0;
-		int8_t offsetY=0;
-		int cursorX = 0;
-		int cursorY = 0;
-		char buf[100];
-		int currentColor = 0;
-		int m_bgColor = 0;
-		systemFont m_Font;
-		Stream& stream;
-		const colorDef<uint8_t> (&colors)[nColors];
-		uartOut(
-				Stream& stream,
-				const colorDef<uint8_t> (&c)[nColors],
-				idx_t* t,
-				panelsList &p,
-				systemFont font = font24,
-				idx_t offsetX=0,
-				idx_t offsetY=0,
-				int fontMarginY=1
-			) :gfxOut(font/2,font,t,p,(styles)(menuOut::redraw|menuOut::rasterDraw)),stream(stream),colors(c)
-		{
-			this->offsetX=offsetX;
-			this->offsetY=offsetY;
-			this->fontMarginY=fontMarginY;
-			this->m_Font = font;
-		}
-
-		size_t write(uint8_t ch) override
-		{
-			sprintf(buf,"SBC(%d);DCV%d(%d,%d,'%c',%d);", m_bgColor, m_Font, cursorX, cursorY - resY + fontMarginY, (char)ch, currentColor);
-			sendCommand(buf);
-			cursorX = cursorX + resX;
-			return 1;
-		}
-
-		inline uint8_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const
-		{
-			return memByte(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-		}
-
-		void setBgColor(colorDefs c,bool selected=false,status s=enabledStatus,bool edit=false)
-		{
-			m_bgColor = getColor(c,selected,s,edit);
-		}
-
-		void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool edit=false) override
-		{
-			currentColor = getColor(c,selected,s,edit);
-		}
-
-		void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override
-		{
-			const panel p=panels[panelNr];
-			setBgColor(color,selected,stat,edit);
-			drawBox(p.x*resX + offsetX, (p.y+ln)*resY + offsetY, maxX()*resX, resY);
-		}
-
-		void clear() override
-		{
-			sendCommand("CLR(7);");
-			panels.reset();
-		}
-
-		void clear(idx_t panelNr) override
-		{
-			const panel p=panels[panelNr];
-			setBgColor(bgColor,false,enabledStatus,false);;
-			drawBox(p.x*resX + offsetX,p.y*resY + offsetY,p.w*resX,p.h*resY);
-			panels.nodes[panelNr]=NULL;
-		}
-
-		void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override
-		{
-			const panel p=panels[panelNr];
-			setBgColor(c, selected, stat, edit);
-			drawFrame((p.x+x)*resX,(p.y+y)*resY, w*resX, h*resY);
-		}
-
-		void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override
-		{
-			const panel p=panels[panelNr];
-			setBgColor(c, selected, stat, edit);
-			drawBox((p.x+x)*resX, (p.y+y)*resY, w*resX, h*resY);
-		}
-
-		void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override
-		{
-			const panel p=panels[panelNr];
-			cursorX = (p.x+x)*resX+fontMarginX + offsetX;
-			cursorY = (p.y+y+1)*resY-fontMarginY + offsetY;
-		}
-
-		void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override
-		{
-			const panel p=panels[panelNr];
-			setBgColor(cursorColor,selected,stat);
-			drawFrame(p.x*resX + offsetX, (p.y+ln)*resY + offsetY, maxX()*resX, resY);
-		}
-
-		idx_t printRaw(const char* at,idx_t len) override
-		{
-			sprintf_P(buf,PSTR("SBC(%d);DCV%d(%d,%d,'%S',%d);"), m_bgColor, m_Font, cursorX, cursorY - resY + fontMarginY, at, currentColor);
-			sendCommand(buf);
-			cursorX = cursorX + strlen_P(at)*resX;
-			return strlen_P(at);
-		}
-
-	private:
-
-		void checkStreamReady()
-		{
-			int cnt = 0, timeOutCounter = 1000;
-			while (timeOutCounter-- > 0)
-			{
-				delay(1);
-				if (stream.available() > 0)
-				{
-					stream.read();
-					if (++cnt == 4) break;
-				}
-			}
-		}
-
-		void sendCommand(char * cmd)
-		{
-			stream.println(cmd);
-			//Serial.println(cmd);
-			checkStreamReady();
-		}
-
-		void drawFrame(int x, int y, int w, int h)
-		{
-			sprintf(buf, "BOX(%d,%d,%d,%d,%d);", x, y, x + w, y + h, m_bgColor);
-			sendCommand(buf);
-		}
-
-		void drawBox(int x, int y, int w, int h)
-		{
-			sprintf(buf, "BOXF(%d,%d,%d,%d,%d);", x, y, x + w, y + h, m_bgColor);
-			sendCommand(buf);
-		}
-	};
-}
-#endif //RSITE_ARDUINOP_MENU_UART
diff --git a/src/menuIO/urtouchIn.h b/src/menuIO/urtouchIn.h
deleted file mode 100644
index 1f859846..00000000
--- a/src/menuIO/urtouchIn.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- C++ -*- */
-
-/**************
-UTouch driver for arduino menu
-turning utouch data into a menu input stream
-checks menu option clicked or do menu scroll on drag
-
-www.r-site.net
-
-Dec. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-UTouch library from:
-  http://henningkarlsen.com/electronics/library.php?id=56
-***/
-#ifndef RSITE_ARDUINO_MENU_UTOUCH
-  #define RSITE_ARDUINO_MENU_UTOUCH
-
-  #include <URTouch.h>
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    class menuUTouch:public menuIn {
-    public:
-      URTouch& touch;
-      navRoot& root;
-      gfxOut& out;
-      int startX,startY;
-      int scrlY;
-      bool touching;
-      bool dragging;
-      unsigned long evTime;
-      menuUTouch(URTouch& t,navRoot& root,gfxOut& out):touch(t),root(root),out(out),touching(false),dragging(false) {}
-      int available(void) {return touch.dataAvailable()?1:touching;}
-      int peek(void) {return -1;}
-      int read() {
-        menuNode& m=root.active();
-        panel p=out.panels[out.panels.cur];
-        if (touch.dataAvailable()) {
-          if (root.sleepTask) return options->navCodes[enterCmd].ch;
-          evTime=millis();
-          touch.read();
-          startX=touch.getX()-p.x*out.resX;
-          if (startX>out.maxX()*out.resX) return -1;
-          int y=touch.getY()-p.y*out.resY;//-menuNode::activeNode->oy;
-          if (y<0||y>out.maxY()*out.resY) return -1;
-          //within menu box
-          if (touching) {//might be dragging
-            int d=scrlY-y;
-            int ad=abs(d);
-            if (ad>(out.resY>>1)&&(ad<<1)>out.resY) {
-              dragging=true;//we consider it a drag
-              scrlY-=(d>0?1:-1)*(out.resY/2);
-              //prompt* nf=root.navFocus;
-              /*if (nf->isMenu()&&!nf->isVariant()) {
-                MENU_DEBUG_OUT<<"utouch scrolling "<<(d>0?"Up":"Down")<<endl;
-                return (d>0?options->navCodes[scrlUpCmd].ch:options->navCodes[scrlDownCmd].ch);
-              } else {*/
-                //MENU_DEBUG_OUT<<"utouch moving "<<(d>0?"Up":"Down")<<endl;
-                return (d>0?options->navCodes[upCmd].ch:options->navCodes[downCmd].ch);
-              //}
-            }
-          }  else {//start new touching
-            touching=true;
-            dragging=false;
-            startY=y;
-            scrlY=y;
-            evTime=millis();
-          }
-        } else {
-          if (millis()-evTime<200) return -1;//debouncing
-          touching=false;//touch ending
-          if (dragging) return -1;
-          int st=root.showTitle?1:0;
-          if (root.navFocus->isMenu()&&!root.navFocus->parentDraw()) {
-            int at=startY/out.resY;
-            //MENU_DEBUG_OUT<<"utouch index select "<<((at>=st&&at<(m.sz()+st))?at-st+out.top(root.node())+'1':-1)<<endl;
-            //MENU_DEBUG_OUT<<"canNav:"<<root.navFocus->canNav()<<"isVariant:"<<root.navFocus->isVariant()<<endl;
-            return (at>=st&&at<(m.sz()+st))?at-st+out.top(root.node())+'1':-1;
-          } else {//then its some sort of field
-            prompt& a=m;//root.active();
-            //MENU_DEBUG_OUT<<"utouch "<<(memStrLen(a.shadow->text)*out.resX<startX?"enter":"escape")<<endl;
-            return
-              ((int)(memStrLen(a.getText())*out.resX))<startX?
-                options->navCodes[enterCmd].ch:
-                options->navCodes[escCmd].ch;
-          }
-        }
-        return -1;
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/utftOut.h b/src/menuIO/utftOut.h
deleted file mode 100644
index c379864f..00000000
--- a/src/menuIO/utftOut.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- C++ -*- */
-
-/********************
-Use UTFT graphics display as menu output
-
-www.r-site.net
-
-Dec. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-UTFT library from:
-  http://www.rinkydinkelectronics.com/library.php?id=51
-  http://henningkarlsen.com/electronics/library.php?id=50 (old address)
-
-***/
-#ifndef RSITE_ARDUINO_MENU_UTFT
-	#define RSITE_ARDUINO_MENU_UTFT
-
-  #ifdef USING_PGM
-    #include <avr/pgmspace.h>
-  #else
-  	#undef pgm_read_word
-  	#undef pgm_read_byte
-  #endif
-	#include <UTFT.h>
-	#include "../menuDefs.h"
-
-  namespace Menu {
-
-    #define RGB565(r,g,b) ((((r>>3)<<11) | ((g>>2)<<5) | (b>>3)))
-
-    class utftOut:public gfxOut {
-      public:
-        UTFT& gfx;
-        const colorDef<uint16_t> (&colors)[nColors];
-        int curX,curY;
-        utftOut(UTFT& tft,const colorDef<uint16_t> (&c)[nColors],idx_t* t,panelsList &p,idx_t resX,idx_t resY)
-          :gfxOut(resX,resY,t,p),gfx(tft),colors(c),curX(0),curY(0) {}
-        /*void init() {
-          //setup geometry
-          resX=gfx.getFontXsize();
-          resY=gfx.getFontYsize();
-          //maxX=gfx.getDisplayXSize()/resX;
-          //maxY=gfx.getDisplayYSize()/resY;
-        }*/
-
-        inline uint16_t getColor(colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) const {
-          return memWord(&(stat==enabledStatus?colors[color].enabled[selected+edit]:colors[color].disabled[selected]));
-        }
-
-        void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool e=false) override {
-          gfx.setColor(getColor(c,selected,s,e));
-				}
-
-				inline int clipX(int x) {return x<0?0:x>gfx.getDisplayXSize()-1?gfx.getDisplayXSize()-1:x;}
-				inline int clipY(int y) {return y<0?0:y>gfx.getDisplayYSize()-1?gfx.getDisplayYSize()-1:y;}
-
-        void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override {
-					const panel p=panels[panelNr];
-					uint16_t c=getColor(color,selected,stat,edit);
-          gfx.setColor(c);
-					gfx.fillRect(clipX(p.x*resX),clipY((p.y+ln)*resY),clipX((p.x+p.maxX())*resX),clipY((p.y+ln+1)*resY));
-					gfx.setBackColor(c);
-		    	//setCursor(0,ln);
-		    }
-
-        void clear() override {
-					panels.reset();
-          gfx.setBackColor(getColor(bgColor,false,enabledStatus,false));
-          gfx.clrScr();
-					curX=curY=0;
-				}
-
-        virtual void clear(idx_t panelNr) override {
-					const panel p=panels[panelNr];
-          gfx.setColor(getColor(bgColor,false,enabledStatus,false));
-					gfx.fillRect(clipX(p.x*resX),clipY(p.y*resY),clipX((p.x+p.w)*resX),clipY((p.y+p.h)*resY));
-					//MENU_DEBUG_OUT<<"panel:"<<panelNr<<"("<<p.x<<","<<p.y<<","<<(p.x+p.w)<<","<<(p.y+p.h)<<")"<<endl;
-					//MENU_DEBUG_OUT<<"rect("<<p.x*resX<<","<<p.y*resY<<","<<(p.x+p.w)*resX<<","<<(p.y+p.h)*resY<<")"<<endl;
-					//MENU_DEBUG_OUT<<"fillRect("<<clipX(p.x*resX)<<","<<clipY(p.y*resY)<<","<<clipX((p.x+p.w)*resX)<<","<<clipY((p.y+p.h)*resY)<<")"<<endl;
-					panels.nodes[panelNr]=NULL;
-				}
-
-        void setCursor(idx_t x,idx_t y,idx_t panelNr=0) override {
-          const panel p=panels[panelNr];
-    	    curX=(p.x+x)*resX;
-    	    curY=(p.y+y)*resY+fontMarginY;
-    	  }
-
-				void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0) override {
-					const panel p=panels[panelNr];
-					// gfxOut::drawCursor(ln,selected,stat);
-					gfx.setColor(getColor(cursorColor,selected,enabledStatus,false));
-					gfx.drawRect(clipX(p.x*resX),clipY((p.y+ln)*resY),clipX((p.x+p.maxX())*resX),clipY((p.y+ln+1)*resY));
-				}
-
-        size_t write(uint8_t ch) override {
-          switch(ch) {
-          case 0x0D://NL
-            curX=0;
-            break;
-          case 0x0A://CR
-            curY+=resY;
-            break;
-          default:
-            gfx.printChar(ch,curX,curY);
-            curX+=resX;
-          }
-          return 1;
-        }
-    };
-
-  }//namespace Menu
-#endif
diff --git a/src/menuIO/utouchIn.h b/src/menuIO/utouchIn.h
deleted file mode 100644
index a038cf57..00000000
--- a/src/menuIO/utouchIn.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* -*- C++ -*- */
-
-/**************
-UTouch driver for arduino menu
-turning utouch data into a menu input stream
-checks menu option clicked or do menu scroll on drag
-
-www.r-site.net
-
-Dec. 2014 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-UTouch library from:
-  http://henningkarlsen.com/electronics/library.php?id=56
-***/
-#ifndef RSITE_ARDUINO_MENU_UTOUCH
-  #define RSITE_ARDUINO_MENU_UTOUCH
-
-  #include <UTouch.h>
-  #include "../menuDefs.h"
-
-  namespace Menu {
-
-    class menuUTouch:public menuIn {
-    public:
-      UTouch& touch;
-      navRoot& root;
-      gfxOut& out;
-      int startX,startY;
-      int scrlY;
-      bool touching;
-      bool dragging;
-      unsigned long evTime;
-      menuUTouch(UTouch& t,navRoot& root,gfxOut& out):touch(t),root(root),out(out),touching(false),dragging(false) {}
-      int available(void) {return touch.dataAvailable()?1:touching;}
-      int peek(void) {return -1;}
-      int read() {
-        menuNode& m=root.active();
-        panel p=out.panels[out.panels.cur];
-        if (touch.dataAvailable()) {
-          if (root.sleepTask) return options->navCodes[enterCmd].ch;
-          evTime=millis();
-          touch.read();
-          startX=touch.getX()-p.x*out.resX;
-          if (startX>out.maxX()*out.resX) return -1;
-          int y=touch.getY()-p.y*out.resY;//-menuNode::activeNode->oy;
-          if (y<0||y>out.maxY()*out.resY) return -1;
-          //within menu box
-          if (touching) {//might be dragging
-            int d=scrlY-y;
-            int ad=abs(d);
-            if (ad>(out.resY>>1)&&(ad<<1)>out.resY) {
-              dragging=true;//we consider it a drag
-              scrlY-=(d>0?1:-1)*(out.resY/2);
-              //prompt* nf=root.navFocus;
-              /*if (nf->isMenu()&&!nf->isVariant()) {
-                MENU_DEBUG_OUT<<"utouch scrolling "<<(d>0?"Up":"Down")<<endl;
-                return (d>0?options->navCodes[scrlUpCmd].ch:options->navCodes[scrlDownCmd].ch);
-              } else {*/
-                //MENU_DEBUG_OUT<<"utouch moving "<<(d>0?"Up":"Down")<<endl;
-                return (d>0?options->navCodes[upCmd].ch:options->navCodes[downCmd].ch);
-              //}
-            }
-          }  else {//start new touching
-            touching=true;
-            dragging=false;
-            startY=y;
-            scrlY=y;
-            evTime=millis();
-          }
-        } else {
-          if (millis()-evTime<200) return -1;//debouncing
-          touching=false;//touch ending
-          if (dragging) return -1;
-          int st=root.showTitle?1:0;
-          if (root.navFocus->isMenu()&&!root.navFocus->parentDraw()) {
-            int at=startY/out.resY;
-            //MENU_DEBUG_OUT<<"utouch index select "<<((at>=st&&at<(m.sz()+st))?at-st+out.top(root.node())+'1':-1)<<endl;
-            //MENU_DEBUG_OUT<<"canNav:"<<root.navFocus->canNav()<<"isVariant:"<<root.navFocus->isVariant()<<endl;
-            return (at>=st&&at<(m.sz()+st))?at-st+out.top(root.node())+'1':-1;
-          } else {//then its some sort of field
-            prompt& a=m;//root.active();
-            //MENU_DEBUG_OUT<<"utouch "<<(memStrLen(a.shadow->text)*out.resX<startX?"enter":"escape")<<endl;
-            return
-              ((int)(memStrLen(a.getText())*out.resX))<startX?
-                options->navCodes[enterCmd].ch:
-                options->navCodes[escCmd].ch;
-          }
-        }
-        return -1;
-      }
-      void flush() {}
-      size_t write(uint8_t v) {return 0;}
-    };
-
-  }//namespace Menu
-
-#endif
diff --git a/src/menuIO/xmlFmt.cpp b/src/menuIO/xmlFmt.cpp
deleted file mode 100644
index fb38e479..00000000
--- a/src/menuIO/xmlFmt.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "../menuDefs.h"
-#ifdef MENU_FMT_WRAPS
-  #include "xmlFmt.h"
-
-  namespace Menu {
-    void outputOptions(menuOut& o,navNode &nav,menuNode& node,idx_t idx) {
-      o<<"<node>";
-      for(idx_t n=0;n<node.sz();n++)
-        o<<"<value"<<(n==node.selected()?" selected=\"selected\"":"")<<">"<<node[n]<<"</value>";
-      o<<"</node>";
-    }
-  };
-#endif
diff --git a/src/menuIO/xmlFmt.h b/src/menuIO/xmlFmt.h
deleted file mode 100644
index 09038a95..00000000
--- a/src/menuIO/xmlFmt.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/* -*- C++ -*- */
-
-#ifndef RSITE_ARDUINO_MENU_XMLFMT
-  #define RSITE_ARDUINO_MENU_XMLFMT
-
-  #ifdef MENU_FMT_WRAPS
-  #include "../menuDefs.h"
-  #include "../items.h"
-  #include "esp8266Out.h"
-
-    namespace Menu {
-
-      // inline Print& operator<<(Print&o, Menu::prompt&p) {
-      //   print_P(o,p.getText());
-      //   return o;
-      // }
-
-      inline menuOut& operator<<(menuOut&o, idx_t i) {
-        o.print(i);
-        return o;
-      }
-
-      inline menuOut& operator<<(menuOut&o, const char* p) {
-        print_P(o,p);
-        return o;
-      }
-
-      // inline Print& operator<<(Print&o, const char* p) {
-      //   print_P(o,p);
-      //   return o;
-      // }
-
-      void outputOptions(menuOut& o,navNode &nav,menuNode& node,idx_t idx);
-
-      //wraps a webserver output and writes xml to it
-      template<class T>
-      class xmlFmt:public T {
-        public:
-          using T::T;
-          result fmt(bool start,prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) {
-            trace(
-              if (start) {
-                *this<<"<!--xml fmt "<<part<<" idx:"<<idx<<(start?" start":" end");
-                // if (target.has(_asPad)) *this<<" MENU_DEBUG=\"target_asPad\"";
-                // if (nav.target->has(_asPad)) *this<<" MENU_DEBUG=\"nav_target_asPad\"";
-                // if (&target==nav.target) *this<<" MENU_DEBUG=\"target_is_nav_target\"";
-                *this<<"-->";
-              });
-            switch(part) {
-              case menuOut::fmtPanel:
-                if (start)
-                  *this<<"\n<panel id=\""<<nav.target->hash()<<"\">";
-                else T::operator<<("</panel>");
-                break;
-              case menuOut::fmtTitle:
-                if (start) T::operator<<("<tit>");
-                else T::operator<<("</tit>");
-                break;
-              case menuOut::fmtBody:
-                if (start) {
-                  *this<<"\n<menu r=\"";
-                  nav.root->printPath(*this,(menuNode*)&target);
-                  *this<<"\">";}
-                else T::operator<<("</menu>");
-                break;
-              case menuOut::fmtUnit:
-                *this<<(start?"<":"</")<<"u>";
-                break;
-              case menuOut::fmtOp:
-                if (start) {
-                  *this<<"\n<op";// id=\""<<target.hash()<<"\"";
-                  if (target.has(_asPad)) *this<<" pad=\"y\"";
-                  if (nav.sel==idx) *this<<" sel=\"y\"";
-                  if (!target.enabled) *this<<" dis=\"y\"";
-                  *this<<" i=\""<<idx<<"\"";
-                  *this<<">";
-                } else T::operator<<("</op>");
-                break;
-              case menuOut::fmtToggle:
-                if (start) {
-                  *this<<"<tog>";
-                  outputOptions(*this,nav,*(menuNode*)&target,idx);
-                  *this<<"</tog><fv><![CDATA[";
-                } else *this<<"]]></fv>";
-                break;
-              case menuOut::fmtPrompt:
-                if (start) {
-                  *this<<"<p"
-                    <<" t=\""<<target.typeName();
-                    // <<"\" i=\""<<idx
-                    // <<"\" ns=\""<<nav.sel
-                    // <<"\" r=\"";
-                    // nav.root->printPath(*this,nav.sel!=idx&&nav.target->has(_asPad)&&(&target!=nav.target)?-1:0);
-                  // *this<<"/"<<idx;
-                  *this<<"\"";
-                  if (&target==nav.target) *this<<" act=\"y\"";
-                  // if (nav.target->has(_asPad)) *this<<" DEBUG1=\"nav_target_asPad\"";
-                  // if (&target==nav.target) *this<<" DEBUG2=\"target_is_nav_target\"";
-                  *this<<"><![CDATA[";
-                } else *this<<"]]></p>";
-                break;
-              case menuOut::fmtSelect:
-                if (start) {
-                  *this<<"<select>";
-                  outputOptions(*this,nav,*(menuNode*)&target,idx);
-                  *this<<"</select><fv><![CDATA[";
-                } else *this<<"]]></fv>";
-                break;
-              case menuOut::fmtChoose:
-                if (start) {
-                  *this<<"<choose>";
-                  outputOptions(*this,nav,*(menuNode*)&target,idx);
-                  *this<<"</choose><fv><![CDATA[";
-                } else *this<<"]]></fv>";
-                break;
-              case menuOut::fmtField:
-                if (start) {
-                  *this<<"<fld h=\"";
-                  target.printHigh(*this);
-                  *this<<"\" l=\"";
-                  target.printLow(*this);
-                  *this<<"\" s=\"";
-                  target.printStep(*this);
-                  *this<<"\" t=\"";
-                  target.printTune(*this);
-                  *this<<"\"><![CDATA[";
-                } else *this<<"]]></fld>";
-                break;
-              case menuOut::fmtEditCursor:
-                if (start) *this<<"<ec><![CDATA[";
-                else *this<<"]]></ec>";
-                break;
-              case menuOut::fmtTextField:
-                if (start) *this<<"<fv><![CDATA[";
-                else *this<<"]]></fv>";
-                break;
-              case menuOut::fmtIdx:
-                if (start) *this<<"<idx><![CDATA[";
-                else *this<<"]]></idx>";
-                break;
-              case menuOut::fmtCursor:
-              case menuOut::fmtCursorOpen:
-              case menuOut::fmtCursorClose:
-                if (start) *this<<"<cur><![CDATA[";
-                else *this<<"]]></cur>";
-                break;
-              case menuOut::fmtOpBody:
-                if (start) *this<<"<ob>";
-                else *this<<"</ob>";
-                break;
-              case menuOut::fmtPreview:
-                if (start) *this<<"<preview>";
-                else *this<<"</preview>";
-                break;
-              default:break;
-            }
-            return proceed;
-          }
-          result fmtStart(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {return fmt(true,target,part,nav,idx);}
-          result fmtEnd(prompt& target,menuOut::fmtParts part,navNode &nav,idx_t idx=-1) override {return fmt(false,target,part,nav,idx);}
-      };
-    }//namespace
-  #endif
-#endif
diff --git a/src/menuIo.cpp b/src/menuIo.cpp
deleted file mode 100644
index ec9c0a01..00000000
--- a/src/menuIo.cpp
+++ /dev/null
@@ -1,482 +0,0 @@
-#include "menuDefs.h"
-using namespace Menu;
-
-void menuIn::setFieldMode(bool) {}
-bool menuIn::fieldMode() const {return false;}
-
-size_t noInput::write(uint8_t) {return 0;}
-int noInput::available() {return 0;}
-int noInput::read() {return -1;}
-int noInput::peek() {return -1;}
-
-#ifdef MENU_ASYNC
-  int StringStream::available() {return 0!=*src;}
-  int StringStream::read() {return *src++;}
-  int StringStream::peek() {return *src?*src:-1;}
-  void StringStream::flush() {while(*src) src++;}
-  size_t StringStream::write(uint8_t) {return 0;}
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-// menuOut - base menu output device
-//
-////////////////////////////////////////////////////////////////////////////////
-#if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-  #ifdef ESP8266
-    template<typename T>
-    menuOut& menuOut::operator<<(T o) {(*(Stream*)this)<<(o);return *this;}
-  #endif
-#endif
-
-#ifdef MENU_ASYNC
-  bool menuOut::isAsync() {return false;}
-#endif
-
-menuOut& menuOut::fill(
-  int x1, int y1, int x2, int y2,char ch,
-  colorDefs color,
-  bool selected,
-  status stat,
-  bool edit
-) {return *this;}
-
-idx_t menuOut::printRaw(const char* at,idx_t len) {
-  trace(MENU_DEBUG_OUT<<"menuOut::printRaw"<<endl);
-  const char* p=at;
-  uint8_t ch;
-  for(int n=0;(ch=memByte(at++))&&(len==0||n<len);n++) {
-    write(ch);
-  }
-  return at-p-1;
-}
-
-void menuOut::doNav(navCmd cmd,navNode &nav) {
-  trace(MENU_DEBUG_OUT<<"menuOut::doNav"<<endl);
-  panel p=panels[nav.root->level];
-  idx_t t=top(nav)-1;
-  idx_t sz=nav.target->sz();
-  switch(cmd.cmd) {
-    case scrlUpCmd:
-      if (t) {
-        t--;
-        if (nav.sel>t+sz) nav.sel--;
-      }
-      break;
-    case scrlDownCmd:
-      if (t+p.h<sz) {
-        t++;
-        if (nav.sel<t) nav.sel++;
-      }
-      break;
-    default: assert(false);
-  }
-}
-
-void menuOut::setColor(colorDefs c,bool selected,status s,bool edit) {}
-void menuOut::drawCursor(idx_t ln,bool selected,status stat,bool edit,idx_t panelNr) {
-  setColor(cursorColor, selected, stat,edit);
-  write(selected?(stat==disabledStatus? options->disabledCursor : options->selectedCursor):' ');
-}
-idx_t menuOut::startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) {write(charEdit?">":"[");return 1;}
-idx_t menuOut::endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) {write(charEdit?"<":"]");return 1;}
-idx_t menuOut::editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr) {return 0;}
-void menuOut::rect(idx_t panelNr,idx_t x,idx_t y,idx_t w,idx_t h,colorDefs c,bool selected,status stat,bool edit) {}
-void menuOut::box(idx_t panelNr,idx_t x,idx_t y,idx_t w,idx_t h,colorDefs c,bool selected,status stat,bool edit) {}
-#ifdef MENU_FMT_WRAPS
-  result menuOut::fmtStart(prompt& target,fmtParts part,navNode &nav,idx_t idx) {return proceed;}
-  result menuOut::fmtEnd(prompt& target,fmtParts part,navNode &nav,idx_t idx) {return proceed;}
-#endif
-
-#if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-menuOut& menuOut::operator<<(const prompt& p) {
-  print_P(*this,p.getText());
-  return *this;
-}
-#endif
-
-void cursorOut::clearLine(idx_t ln,idx_t panelNr,colorDefs color,bool selected,status stat,bool edit) {
-  setCursor(0,ln,panelNr);
-  for(int n=0;n<maxX();n++) print(' ');
-  setCursor(0,ln,panelNr);
-}
-
-menuOut& cursorOut::fill(
-  int x1, int y1, int x2, int y2,char ch,
-  colorDefs color,
-  bool selected,
-  status stat,
-  bool edit
-) {
-  for(int r=y1;r<=y2;r++) {
-    setCursor(x1,r);
-    for(int c=x1;c<=x2;c++)
-      write(ch);
-  }
-  return *this;
-}
-
-idx_t gfxOut::startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) {
-  if (charEdit) {
-    rect(panelNr,  x-1,  y, 1, 1, bgColor, false, enabledStatus, false);
-    setColor(fgColor,false,enabledStatus,false);
-  }/* else
-    box(panelNr,  x,  y, 1, 1, bgColor, false, enabledStatus, false);*/
-  return 0;
-}
-
-idx_t gfxOut::endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) {
-  setColor(fgColor,true,enabledStatus,true);return 0;
-}
-
-idx_t gfxOut::editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr) {
-  //TODO: next version, this furntiosn should return an USED value (and avoid nasty x-1)
-  if (editing) box(panelNr,x-1,y);
-  return 0;
-}
-
-Used outputsList::printMenu(navNode& nav) const {
-  trace(MENU_DEBUG_OUT<<"outputsList::printMenu");
-  for(int n=0;n<cnt;n++) {
-    trace(MENU_DEBUG_OUT.write('.'));
-    menuOut& o=*((menuOut*)memPtr(outs[n]));
-    if ((o.style&(menuOut::rasterDraw))||(o.style&(menuOut::redraw))||nav.changed(o))
-      o.printMenu(nav);
-  }
-  trace(MENU_DEBUG_OUT<<endl);
-  clearChanged(nav);
-  trace(MENU_DEBUG_OUT<<"outputsList::printMenu ended!"<<endl);
-  return 0;
-}
-
-result outputsList::idle(idleFunc f,idleEvent e,bool idleChanged) {
-  #ifdef MENU_DEBUG
-    if (!f) MENU_DEBUG_OUT<<"idleFunc is NULL!!!"<<endl;
-  #endif
-  if (!f) return proceed;
-  trace(MENU_DEBUG_OUT<<"idling on output list cnt:"<<cnt<<endl);
-  for(int n=0;n<cnt;n++) {
-    menuOut& o=*((menuOut*)memPtr(outs[n]));
-    switch(e) {
-      case idleStart:
-        trace(MENU_DEBUG_OUT<<"idleStart"<<endl);
-        if ((*f)(o,e)==proceed) {
-          if (!(o.style&menuOut::redraw)) {
-            result r=(*f)(o,idling);
-            if (r==quit) return r;
-          }
-        } else return quit;
-        break;
-      case idling:
-      trace(MENU_DEBUG_OUT<<"idling"<<endl);
-        if (o.style&menuOut::redraw||(idleChanged&&(o.style&menuOut::minimalRedraw)))
-          return (*f)(o,e);
-        break;
-      case idleEnd:
-        trace(MENU_DEBUG_OUT<<"idle end"<<endl);
-        result r=(*f)(o,e);
-        if (r==quit) return r;
-        break;
-    }
-  }
-  return proceed;
-}
-
-void outputsList::refresh() {
-  for(int n=0;n<cnt;n++) ((menuOut*)memPtr(outs[n]))->drawn=NULL;
-}
-void outputsList::clearChanged(navNode& nav) const {
-  for(int n=0;n<cnt;n++) ((menuOut*)memPtr(outs[n]))->clearChanged(nav);
-}
-void outputsList::clear() {
-  for(int n=0;n<cnt;n++) ((menuOut*)memPtr(outs[n]))->clear();
-}
-// void outputsList::reset() {
-//   for(int n=0;n<cnt;n++) ((menuOut*)memPtr(outs[n]))->reset();
-// }
-void outputsList::doNav(navCmd cmd,class navNode &nav) {
-  for(int n=0;n<cnt;n++) ((menuOut*)memPtr(outs[n]))->doNav(cmd,nav);
-}
-
-// draw a menu preview on a panel
-void menuOut::previewMenu(navRoot& root,menuNode& menu,idx_t panelNr) {
-  trace(MENU_DEBUG_OUT<<"menuOut::previewMenu"<<endl);
-  // #ifdef MENU_FMT_WRAPS
-  //   fmtStart(fmtBody,root.node());
-  // #endif
-  setColor(fgColor,false);
-  if (menu.has(_asPad)) {
-    for(int i=0;i<menu.sz();i++) {
-      prompt& p=menu[i];
-      #ifdef MENU_FMT_WRAPS
-        fmtStart(p,fmtOp,root.node(),i);
-      #endif
-      #ifdef MENU_FMT_WRAPS
-        fmtStart(p,fmtCursor,root.node(),i);
-      #endif
-      setColor(fgColor,false,p.enabled);
-      drawCursor(i,false,p.enabled,false,panelNr);
-      #ifdef MENU_FMT_WRAPS
-        fmtEnd(p,fmtCursor,root.node(),i);
-      #endif
-      setColor(fgColor,false,p.enabled,false);
-      #ifdef MENU_FMT_WRAPS
-        fmtStart(p,fmtOpBody,root.node(),i);
-      #endif
-      p.printTo(root,false,*this,i,panels[panelNr].w,panelNr);
-      #ifdef MENU_FMT_WRAPS
-        fmtEnd(p,fmtOpBody,root.node(),i);
-      #endif
-      #ifdef MENU_FMT_WRAPS
-        fmtEnd(p,fmtOp,root.node(),i);
-      #endif
-    }
-  } else {
-    clear(panelNr);
-    setCursor(0,0,panelNr);
-    for(idx_t i=0;i<maxY(panelNr);i++) {
-      if (i>=menu.sz()) break;
-      prompt& p=menu[i];
-      clearLine(i,panelNr,bgColor,false,p.enabled);
-      setCursor(0,i,panelNr);
-      setColor(fgColor,false,p.enabled);
-      drawCursor(i,false,p.enabled,false,panelNr);
-      setColor(fgColor,false,p.enabled,false);
-      p.printTo(root,false,*this,i,panels[panelNr].w,panelNr);
-    }
-  }
-  // #ifdef MENU_FMT_WRAPS
-  //   fmtEnd(fmtBody,root.node());
-  // #endif
-}
-
-//determin panel number here and distribute menu and previews among the panels
-Used menuOut::printMenu(navNode &nav) {
-  trace(MENU_DEBUG_OUT<<"menuOut::printMenu(navNode &nav)"<<endl);
-  menuNode& focus=nav.root->active();
-  int lvl=nav.root->level;
-  if (focus.parentDraw()) lvl--;
-  navNode& nn=nav.root->path[lvl];
-  int k=(lvl<panels.sz-1)?lvl:panels.sz-1;
-  if ((style&usePreview)&&k) k--;
-  for(int i=0;i<k;i++) {
-    navNode &n=nav.root->path[lvl-k+i];
-    if (!(/*n.has(_asPad)&&*/(style&minimalRedraw)&&panels.nodes[i]==&n)) {
-      previewMenu(*nav.root,*n.target,i);
-      panels.nodes[i]=&n;
-    }
-  }
-  panels.cur=k;
-  printMenu(nn,k);
-  panels.nodes[k]=&nav;//for cleaning purposes
-  for(int i=k+2;i<panels.sz;i++) if (panels.nodes[i]) {
-    clear(i);
-    panels.nodes[i]=NULL;
-  }
-  return 0;
-}
-
-// generic (menuOut) print menu on a panel
-// this function emits format messages
-// to be handler by format wrappers
-Used menuOut::printMenu(navNode &nav,idx_t panelNr) {
-  trace(MENU_DEBUG_OUT<<"menuOut::printMenu(navNode &nav,idx_t panelNr)"<<endl);
-  if (!(nav.root->navFocus->has((systemStyles)(_parentDraw|_menuData)))) {
-    //on this case we have a navTarget object that draws himself
-    if (nav.root->navFocus->changed(nav,*this,false))
-      nav.root->navFocus->printTo(*nav.root,true,*this,nav.sel,maxX(panelNr),panelNr);
-  } else {
-    idx_t topi=nav.root->level;
-    if(topi&&nav.root->active().parentDraw()) topi--;
-    idx_t ot=tops[topi];
-    bool asPad=nav.target->has(_asPad);
-    idx_t st
-      =((nav.target->style()&showTitle)||(nav.root->showTitle&&(!(nav.target->style()&noTitle))))
-      &&!(asPad||(maxY(panelNr)<2));//do not use titles on single line devices!
-    if (!nav.target->parentDraw()) {
-      if (pageScroll)
-        tops[topi]=nav.sel-(nav.sel%(pageScroll?panels[panelNr].maxY()-st:1));
-      else {
-        while(nav.sel+st>=(tops[topi]+maxY(panelNr))) tops[topi]++;
-        while(nav.sel<tops[topi]||(tops[topi]&&((nav.sz()-tops[topi])<maxY(panelNr)-st)))
-          tops[topi]--;
-      }
-    }
-    bool all=(style&redraw)
-      ||(tops[topi]!=ot)
-      ||(drawn!=nav.target)
-      ||(panels.nodes[panelNr]!=&nav);
-    if (!(all||(style&minimalRedraw))) {//non minimal draw will redraw all if any change
-      trace(MENU_DEBUG_OUT<<"request full draw "<<style<<endl);
-      all|=nav.target->changed(nav,*this);
-    }
-    all|=nav.target->dirty;
-    if (!(all||(style&minimalRedraw))) return 0;
-        panel pan=panels[panelNr];
-
-    //-----> panel start
-    trace(MENU_DEBUG_OUT<<"panel start"<<endl);
-    bool titleChanged=st||nav.target->changed(nav,*this,false);
-    #ifdef MENU_FMT_WRAPS
-      fmtStart(*nav.target,fmtPanel,nav);
-    #endif
-    if (all||titleChanged) {
-      trace(MENU_DEBUG_OUT<<"clear title "<<titleChanged<<endl);
-      trace(MENU_DEBUG_OUT<<"all:"<<all<<" panelNr:"<<panelNr<<endl);
-      trace(MENU_DEBUG_OUT<<"{x:"<<pan.x<<" y:"<<pan.y<<" w:"<<pan.w<<" h:"<<pan.h<<"}"<<endl);
-      if (all&&!asPad) clear(panelNr);
-      if (st||asPad) {
-        ///------> titleStart
-        trace(MENU_DEBUG_OUT<<"title start"<<endl);
-        #ifdef MENU_FMT_WRAPS
-          fmtStart(*nav.target,fmtTitle,nav,-1);
-        #endif
-        if (!asPad) {
-          setColor(titleColor,false);
-          clearLine(0,panelNr,titleColor);
-          setColor(titleColor,true);
-          setCursor(0,0,panelNr);
-          //print('[');
-          nav.target->printTo(*nav.root,true,*this,-1,pan.w-(asPad?1:2),panelNr);
-        }
-        ///<----- titleEnd
-        #ifdef MENU_FMT_WRAPS
-          fmtEnd(*nav.target,fmtTitle,nav,-1);
-        #endif
-        if (asPad) {
-          #ifdef MENU_FMT_WRAPS
-            fmtStart(*nav.target,fmtCursor,nav,-1);
-          #endif
-          print(":");
-          #ifdef MENU_FMT_WRAPS
-            fmtEnd(*nav.target,fmtCursor,nav,-1);
-          #endif
-        }
-      }
-    }
-    //------> bodyStart
-    trace(MENU_DEBUG_OUT<<"body start all:"<<all<<endl);
-    #ifdef MENU_FMT_WRAPS
-      fmtStart(*nav.target,fmtBody,nav);
-    #endif
-    idx_t top=asPad?0:tops[topi];
-    // idx_t idxCnt=top;
-    // idx_t exitCnt=0;
-    for(idx_t i=0;asPad||(i<maxY(panelNr)-st);i++) {
-      int ist=i+st;
-      if (i+top>=nav.sz()) break;
-      prompt& p=nav[i+top];
-      idx_t len=pan.w;
-      if (all||p.changed(nav,*this,false)) {
-        //-------> opStart
-        #ifdef MENU_FMT_WRAPS
-          fmtStart(p,fmtOp,nav,i);
-        #endif
-        bool selected=nav.sel==i+top;
-        bool ed=nav.target==&p;
-        //-----> idxStart
-        #ifdef MENU_FMT_WRAPS
-          fmtStart(p,fmtIdx,nav,i);
-        #endif
-        if (!asPad) {//pad MUST be able of clearing part of a line!!!!!
-          clearLine(ist,panelNr,bgColor,selected,p.enabled);//<-- THIS IS DEPENDENT OF A DROP MENU!!!!
-          setCursor(0,ist,panelNr);//<-- THIS IS MAKING A DROP MENU!!!!
-        }
-        setColor(fgColor,selected,p.enabled,ed);
-        //should we use accels on pads?
-        if (nav.root->useAccel&&(!asPad)&&(drawNumIndex&style)) {//<-- NO INDEX FOR PADS
-          char a=top+i+'1';
-          print('[');
-          // if (p.is(_Exit)) {//this would require an enourmous confusiuon on keyboard accels
-          //   print(exitCnt?'-':'0');
-          //   exitCnt++;
-          // } else {
-            print(a<='9'?a:'-');
-          //   idxCnt++;
-          // }
-          print(']');
-          len-=3;
-        }
-        //<------idxEnd
-        #ifdef MENU_FMT_WRAPS
-          fmtEnd(p,fmtIdx,nav,i);
-        #endif
-        //------> cursorStart
-        #ifdef MENU_FMT_WRAPS
-          fmtStart(p,fmtCursorOpen,nav,i);
-          // fmtStart(p,fmtCursor,nav,i);
-        #endif
-        if (asPad&&selected) print("[");
-        else drawCursor(ist,selected,p.enabled,ed,panelNr);//assuming only one character
-        //<------ cursorEnd
-        #ifdef MENU_FMT_WRAPS
-          fmtEnd(p,fmtCursorOpen,nav,i);
-          // fmtEnd(p,fmtCursor,nav,i);
-        #endif
-        len--;
-        //---->opBodyStart
-        #ifdef MENU_FMT_WRAPS
-          fmtStart(p,fmtOpBody,nav,i);
-        #endif
-        setColor(fgColor,selected,p.enabled,ed);
-        if (len>0) len=p.printTo(*nav.root,selected,*this,i,len,panelNr);
-        if (len>0) {
-          if (asPad) {
-            #ifdef MENU_FMT_WRAPS
-              // fmtStart(p,fmtCursor,nav,i);
-              fmtStart(p,fmtCursorClose,nav,i);
-            #endif
-            print(selected?"]":"");
-            #ifdef MENU_FMT_WRAPS
-              fmtEnd(p,fmtCursorClose,nav,i);
-              // fmtEnd(p,fmtCursor,nav,i);
-            #endif
-            len--;
-          }
-        }
-        //<---opBodyEnd
-        #ifdef MENU_FMT_WRAPS
-          fmtEnd(p,fmtOpBody,nav,i);
-        #endif
-        if (selected&&panels.sz>panelNr+1) {
-          if(p.isMenu()&&!p.asPad()) {
-            //----->  previewStart
-            previewMenu(*nav.root,*(menuNode*)&p,panelNr+1);
-            panels.nodes[panelNr+1]=&nav;
-            //<----  previewEnd
-          } else if (panels.nodes[panelNr+1]) clear(panelNr+1);
-        }
-        //opEnd
-        #ifdef MENU_FMT_WRAPS
-          fmtEnd(p,fmtOp,nav,i);
-        #endif
-      }
-    }
-  }
-  //<-----bodyEnd
-  #ifdef MENU_FMT_WRAPS
-    fmtEnd(*nav.target,fmtBody,nav,-1);
-  #endif
-  drawn=nav.target;
-  //lastSel=nav.sel;
-  //<---- panel end
-  #ifdef MENU_FMT_WRAPS
-    fmtEnd(*nav.target,fmtPanel,nav,-1);
-  #endif
-  trace(MENU_DEBUG_OUT<<"ENDING menuOut::printMenu(navNode &nav,idx_t panelNr)"<<endl);
-  return 0;
-}
-
-void menuOut::clearChanged(navNode &nav) {
-  nav.target->clearChanged(nav,*this,true);
-}
-
-idx_t& menuOut::top(navNode& nav) const {return tops[nav.root->level];}
-
-void cursorOut::clear(idx_t panelNr) {
-  const panel p=panels[panelNr];
-  fill(p.x,p.y,p.x+p.w-1,p.y+p.h-1);
-  setCursor(0,0,panelNr);
-  panels.nodes[panelNr]=NULL;
-}
diff --git a/src/menuIo.h b/src/menuIo.h
deleted file mode 100644
index 3b1beeca..00000000
--- a/src/menuIo.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* -*- C++ -*- */
-#ifndef RSITE_ARDUINO_MENU_SYSTEM_IO
-  #define RSITE_ARDUINO_MENU_SYSTEM_IO
-
-  #include "menuBase.h"
-  #include "shadows.h"
-
-  namespace Menu {
-    //inline menuOut::styles operator | (menuOut::styles a, menuOut::styles b) {return (menuOut::styles)(a|b);}
-
-    ///////////////////////////////////////////////////////////////////////////
-    // base for all menu input devices
-    class menuIn:public Stream {
-      public:
-        bool numValueInput=true;
-        //when inside a field some devices might invert the movement axis
-        virtual void setFieldMode(bool);
-        virtual bool fieldMode() const;
-        inline void fieldOn() {setFieldMode(true);}
-        inline void fieldOff() {setFieldMode(false);}
-    };
-
-    class noInput:public menuIn {
-    public:
-      size_t write(uint8_t) override;
-      int available() override;
-      int read() override;
-      int peek() override;
-    };
-
-    #ifdef MENU_ASYNC
-      class StringStream:public menuIn {
-        public:
-          const char *src;
-          inline StringStream(const char*s):src(s) {}
-          int available() override;
-          int read() override;
-          int peek() override;
-          void flush() override;
-          size_t write(uint8_t) override;
-          inline operator const String() {return String(src);}
-      };
-    #endif
-
-    ///////////////////////////////////////////////////////////////////////////
-    // base for all menu output devices
-    class menuOut:public Print {
-      friend class prompt;
-      public:
-        idx_t* tops;
-        panelsList& panels;
-        idx_t lastSel=-1;
-        //TODO: turn this bool's into bitfield flags
-        enum styles {
-          none=0<<0, // default serialOut
-          redraw=1<<0,// changing one part implies printing all visible (deprecated)
-          minimalRedraw=1<<1, // can draw part of the screen
-          drawNumIndex=1<<2, // numerical index should be displayed
-          usePreview=1<<3, // reserve one panel for preview
-          expandEnums=1<<4, // enumerated typed should be printed along with the option (web interface)
-          rasterDraw=1<<5 // can request multiple draws to complete a screen
-        } style;
-        enum fmtParts {
-          fmtPanel,fmtTitle,fmtBody,fmtOp,
-          fmtIdx,fmtCursor,fmtOpBody,fmtPreview,
-          fmtPrompt,fmtField,fmtToggle,fmtSelect,
-          fmtChoose,fmtUnit,fmtTextField,fmtCursorOpen,
-          fmtCursorClose,fmtValue,fmtEditCursor
-        };
-        menuNode* drawn=NULL;
-        bool pageScroll=false;
-        inline menuOut(idx_t *topsList,panelsList &p,styles os=minimalRedraw)
-          :tops(topsList),panels(p),style(os) {}
-        idx_t maxX(idx_t i=0) const;
-        idx_t maxY(idx_t i=0) const;
-        idx_t& top(navNode& nav) const;
-        // inline void reset() {panelsList.reset();}
-        inline idx_t printRaw(const __FlashStringHelper* at,idx_t len) {
-          return printRaw((const char*)at,len);
-        }
-        virtual idx_t printRaw(const char* at,idx_t len);
-        #if defined(MENU_DEBUG) || defined(MENU_ASYNC)
-          virtual menuOut& operator<<(prompt const &p);
-          #ifdef ESP8266
-            template<typename T> menuOut& operator<<(T o);
-          #endif
-        #endif
-        virtual menuOut& fill(
-          int x1, int y1, int x2, int y2,char ch=' ',
-          colorDefs color=bgColor,
-          bool selected=false,
-          status stat=enabledStatus,
-          bool edit=false
-        );
-        void clearChanged(navNode &nav);//clean up changed flags after everyone printed!
-        void previewMenu(navRoot& root,menuNode& menu,idx_t panelNr);//draw a preview on a panel
-        Used printMenu(navNode &nav);//print menus and previews on panels
-        void doNav(navCmd cmd,navNode &nav);
-        virtual void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false)=0;
-        virtual void clear()=0;
-        virtual void clear(idx_t panelNr)=0;
-        virtual void setCursor(idx_t x,idx_t y,idx_t panelNr=0)=0;
-        virtual void setColor(colorDefs c,bool selected=false,status s=enabledStatus,bool edit=false);
-        virtual void drawCursor(idx_t ln,bool selected,status stat,bool edit=false,idx_t panelNr=0);
-        //text editor cursors
-        virtual idx_t startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0);
-        virtual idx_t endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr=0);
-        virtual idx_t editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr=0);
-        virtual void rect(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false);
-        virtual void box(idx_t panelNr,idx_t x,idx_t y,idx_t w=1,idx_t h=1,colorDefs c=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false);
-        #ifdef MENU_FMT_WRAPS
-          virtual result fmtStart(prompt& target,fmtParts part,navNode &nav,idx_t idx=-1);
-          virtual result fmtEnd(prompt& target,fmtParts part,navNode &nav,idx_t idx=-1);
-        #endif
-        #ifdef MENU_ASYNC
-          virtual bool isAsync();
-        #endif
-      protected:
-        Used printMenu(navNode &nav,idx_t panelNr);
-    };
-
-    //for devices that can position a print cursor (like LCD's)
-    class cursorOut:public menuOut {
-    public:
-      inline cursorOut(idx_t *topsList,panelsList &p,styles os=minimalRedraw)
-        :menuOut(topsList,p,os) {}
-      void clearLine(idx_t ln,idx_t panelNr=0,colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override;
-      void clear(idx_t panelNr) override;
-      menuOut& fill(int x1, int y1, int x2, int y2,char ch=' ',colorDefs color=bgColor,bool selected=false,status stat=enabledStatus,bool edit=false) override;
-    };
-
-    //base for graphics displays
-    class gfxOut:public menuOut {
-      public:
-        idx_t resX=1;
-        idx_t resY=1;
-        idx_t fontMarginX=1;//in pixels, compensate vertical font alignment
-        idx_t fontMarginY=1;//in pixels, compensate vertical font alignment
-        inline gfxOut(idx_t rx,idx_t ry,idx_t* t,panelsList &p,menuOut::styles st=menuOut::minimalRedraw,idx_t fontMarginY=1)
-          :menuOut(t,p,st),resX(rx),resY(ry),fontMarginY(fontMarginY) {}
-        idx_t startCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) override;
-        idx_t endCursor(navRoot& root,idx_t x,idx_t y,bool charEdit,idx_t panelNr) override;
-        idx_t editCursor(navRoot& root,idx_t x,idx_t y,bool editing,bool charEdit,idx_t panelNr) override;
-    };
-
-    #ifdef MENU_ASYNC
-      template<typename O>
-      class asyncOut:public O {
-        using O::O;
-        bool isAsync() override {return true;}
-      };
-      using webOut=asyncOut<menuOut>;
-    #endif
-
-    //list of output devices
-    //this allows parallel navigation on multiple devices
-    class outputsList {
-      public:
-        int cnt=1;
-        menuOut* constMEM* outs;
-        outputsList(menuOut* constMEM o[],int n):cnt(n),outs(o) {}
-        inline menuOut& operator[](idx_t i) {
-          assert(i<cnt);
-          return *(menuOut*)memPtr(outs[i]);
-        }
-        Used printMenu(navNode& nav) const;
-        void refresh();//force redraw of all outputs on next output call
-        void clearChanged(navNode& nav) const;
-        void clear();
-        // void reset();
-        void doNav(navCmd cmd,class navNode &nav);
-        result idle(idleFunc f,idleEvent e,bool idleChanged=false);
-    };
-  }//namespace Menu
-
-  #include "nav.h"
-  using namespace Menu;
-  inline idx_t menuOut::maxX(idx_t i) const {return panels[i].w;}
-  inline idx_t menuOut::maxY(idx_t i) const {return panels[i].h;}
-
-#endif
diff --git a/src/nav.cpp b/src/nav.cpp
deleted file mode 100644
index 91d8c103..00000000
--- a/src/nav.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-#include "menuDefs.h"
-using namespace Menu;
-
-void panelsList::reset(idx_t from) {for(int n=from;n<sz;n++) nodes[n]=NULL;}
-idx_t panelsList::maxX() const {
-  idx_t r=0;
-  for(int n=0;n<sz;n++) r=_MAX(operator[](n).maxX(),r);
-  return r;
-}
-idx_t panelsList::maxY() const {
-  idx_t r=0;
-  for(int n=0;n<sz;n++) r=_MAX(operator[](n).maxY(),r);
-  return r;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-// navNode - Navigation layer controller
-//
-////////////////////////////////////////////////////////////////////////////////
-
-navCmd navNode::navKeys(char ch) {
-  trace(MENU_DEBUG_OUT<<"navNode::navKeys"<<endl);
-  if (root->useAccel&&strchr(numericChars,ch)) {
-    return navCmd(idxCmd,ch-'1');
-  }
-  for(uint8_t i=0;i<sizeof(options->navCodes)/sizeof(navCode);i++)
-    if (options->navCodes[i].ch==ch) return options->navCodes[i].cmd;
-  return noCmd;
-}
-
-// generic navigation (aux function)
-navCmd navNode::doNavigation(navCmd cmd) {
-  trace(MENU_DEBUG_OUT<<"navNode::doNavigation"<<endl);
-  idx_t osel=sel;
-  idx_t nsel=sel;
-  navCmd rCmd=cmd;
-  bool changed=false;
-  // trace(if(cmd.cmd!=noCmd) MENU_DEBUG_OUT<<"navigate "<<*target<<" with command:"<<cmd.cmd<<" index:"<<nsel<<endl);
-  switch(cmd.cmd) {
-    /*case scrlDownCmd:
-      if (!target->isVariant())
-        root->out.doNav(cmd,*this);*/
-    case upCmd:
-      // trace(MENU_DEBUG_OUT<<"up"<<endl;);
-      nsel++;
-      if (nsel>=sz()) {if(wrap()) nsel=0; else nsel=sz()-1;}
-      // trace(MENU_DEBUG_OUT<<"new sel:"<<nsel<<endl);
-      break;
-      /*case scrlUpCmd:
-        if (!target->isVariant())
-          root->out.doNav(cmd,*this);*/
-    case downCmd:
-      // trace(MENU_DEBUG_OUT<<"down"<<endl);
-      if (nsel||!target->is(_asPad)) {
-        nsel--;
-        if (nsel<0) {if(wrap()) nsel=sz()-1; else nsel=0;}
-        break;
-      }
-    case escCmd:
-      assert(root);
-      rCmd=root->exit();
-      break;
-    case enterCmd:
-      assert(root);
-      rCmd=root->enter();
-      break;
-    case selCmd:
-    case idxCmd: {
-        idx_t at=(idx_t)cmd.param;//-'1';send us numeric index pls!
-        if (at>=0&&at<sz()) {
-          changed=true;
-          nsel=at;
-        }
-      }
-      break;
-    case noCmd:
-    default: break;
-  }
-  // trace(MENU_DEBUG_OUT<<"changed:"<<changed<<" sels?"<<(osel!=nsel)<<endl);
-  if((osel!=nsel)||changed) {//selection changed, must have been and idx/sel or an up/down movement
-    // trace(MENU_DEBUG_OUT<<"changed"<<endl);
-    if (target->sysStyles()&(_parentDraw|_isVariant)) {
-      trace(MENU_DEBUG_OUT<<"setting dirty"<<endl);
-      target->dirty=true;
-      //this works but might be too much, we dont want to invaludate all the menu!
-      // if (_parentDraw/*&&root->level*/) root->path[root->level-1].target->dirty=true;
-    } else {
-      operator[](osel).dirty=true;
-      operator[](nsel).dirty=true;
-    }
-    //send focus In/Out events
-    if (selBlurEvent&target->events()) target->operator()(selBlurEvent,*this,*target);
-    event(blurEvent,osel);
-    sel=nsel;
-    if (cmd.cmd==selCmd||cmd.cmd==idxCmd) {//do accelerator and enter the option
-      assert(root);
-      rCmd=root->enter();
-    }//other commands up/down just receive focus events
-    event(focusEvent,nsel);
-    if (selFocusEvent&target->events()) target->operator()(selFocusEvent,*this,*target);
-  } //else its an enter/esc or a non-changing index!
-  //MENU_DEBUG_OUT<<"doNavigation returning "<<rCmd<<endl;
-  return rCmd;
-}
-
-result navNode::event(eventMask e,idx_t i) {
-  trace(MENU_DEBUG_OUT<<"navNode::event"<<endl);
-  prompt& p=operator[](i);
-  eventMask m=p.events();
-  eventMask me=(eventMask)(e&m);
-  if (me) return p.eventHandler(e,*this,i);//p(e,p);
-  return proceed;
-}
-
-result navNode::sysEvent(eventMask e,idx_t i) {
-  trace(MENU_DEBUG_OUT<<"navNode::sysEvent"<<endl);
-  prompt& p=operator[](i);
-  return p(e,*this,p);
-}
-
-void navRoot::initPath(idx_t d) {
-  for(idx_t n=0;n<=d;n++)//initialize path chain for this root (v4.0)
-    path[n].root=this;
-}
-void navRoot::useMenu(menuNode &menu) {
-  path[0].useMenu(menu);
-  reset();
-  refresh();
-}
-
-Used navRoot::printMenu() const {
-  trace(MENU_DEBUG_OUT<<"printMenu()"<<endl);
-  if ((active().sysStyles()&_parentDraw)&&level)
-    return out.printMenu(path[level-1]);
-  else return out.printMenu(node());
-}
-
-void navRoot::doInput(menuIn& in) {
-  trace(MENU_DEBUG_OUT<<"navRoot::doInput"<<endl);
-  if (sleepTask) {
-    char c=in.read();
-    if (options->getCmdChar(enterCmd)==c || options->getCmdChar(escCmd)==c) idleOff();
-  } else {
-    idx_t inputBurstCnt=inputBurst+1;
-    //if (in.available())
-    while ((!sleepTask)&&in.available()&&(--inputBurstCnt)) {//if not doing something else and there is input
-      //MENU_DEBUG_OUT.print(".");
-      navFocus->parseInput(node(),in);//deliver navigation input task to target...
-    }
-  }
-  trace(MENU_DEBUG_OUT<<"navRoot::doInput ended!"<<endl);
-}
-
-void navRoot::doOutput() {
-  trace(Serial<<"navRoot::doOutput "<<(int)sleepTask<<endl);
-  if (!sleepTask) printMenu();
-  else {
-    bool c=idleChanged;
-    idleChanged=false;//turn it off here so that sleepTask can force it on again
-    out.idle(sleepTask,idling,c);
-    #ifdef MENU_IDLE_BKGND//cascade menu sysrtem idle behind user idle task
-      if (idleTask!=sleepTask) out.idle(idleTask,idling);
-    #endif
-  }
-}
-
-void navRoot::doNav(navCmd cmd) {
-  trace(MENU_DEBUG_OUT<<"navRoot::doNav"<<endl);
-  if (sleepTask&&(cmd.cmd==enterCmd || cmd.cmd==escCmd)) idleOff();
-  else if (!sleepTask) switch (cmd.cmd) {
-    case scrlUpCmd:
-    case scrlDownCmd:
-      out.doNav(cmd,node());//scroll is perceived better at output device
-      break;
-    default:
-      navFocus->doNav(node(),cmd);
-  }
-}
-
-navCmd navRoot::enter() {
-  trace(MENU_DEBUG_OUT<<"navRoot::enter"<<endl);
-  if (
-    selected().enabled
-    &&selected().sysHandler(activateEvent,node(),selected())==proceed
-  ) {
-    trace(MENU_DEBUG_OUT<<"enabled by syshandler"<<endl);
-    prompt& sel=selected();
-    bool canNav=sel.canNav();
-    bool isMenu=sel.isMenu();
-    result go=node().event(enterEvent);//item event sent here
-    navCmd rCmd=enterCmd;
-    trace(Serial<<"go:"<<go<<" isMenu:"<<isMenu<<" canNav:"<<canNav<<endl;);
-    if (go==proceed&&isMenu&&canNav) {
-      trace(MENU_DEBUG_OUT<<"go for canNav && isMenu"<<endl);
-      if (level<maxDepth) {
-        trace(MENU_DEBUG_OUT<<"level<maxDepth"<<endl);
-        active().dirty=true;
-        menuNode* dest=(menuNode*)&selected();
-        level++;
-        node().target=dest;
-        //if (node().has(_menuData))
-        node().sel=0;
-        active().dirty=true;
-        sel.sysHandler(enterEvent,node(),selected());
-        rCmd=enterCmd;
-      } else {
-        idleOn(maxDepthError);
-        rCmd=noCmd;
-      }
-    } else if (go==quit&&!selected().isMenu()) exit();
-    if (canNav) {
-      trace(MENU_DEBUG_OUT<<"canNav "<<path[level].sel<<endl);
-      navFocus=(navTarget*)&sel;
-      navFocus->dirty=true;
-      if (!isMenu) in.fieldOn();
-    }
-    //node().event(activateEvent);//item is active.. not here, root info is not set yet
-    return rCmd;
-  }
-  return noCmd;
-}
-
-navCmd navRoot::exit() {
-  trace(MENU_DEBUG_OUT<<"navRoot::exit"<<endl);
-  navFocus->dirty=true;
-  if (navFocus->isMenu()) {
-    if (level) {
-      level--;
-      node().event(exitEvent,node().sel);
-    } else if (canExit) {
-      node().event(exitEvent,node().sel);
-      idleOn(idleTask);
-    }
-  } else {
-    node().event(exitEvent,node().sel);
-    in.fieldOff();
-  }
-  active().dirty=true;
-  navFocus=&active();
-  if (navFocus->asPad()) exit();
-  return escCmd;
-}
-
-void navRoot::idleOn(idleFunc task) {
-  out.clear();
-  sleepTask=task;
-  idleChanged=true;
-  active().dirty=true;
-  out.idle(sleepTask,idleStart);
-  #ifdef MENU_IDLE_BKGND
-    if (idleTask!=sleepTask) out.idle(idleTask,idleStart);
-  #endif
-}
-
-void navRoot::idleOff() {
-  out.idle(sleepTask,idleEnd);
-  #ifdef MENU_IDLE_BKGND
-    if (idleTask!=sleepTask) out.idle(idleTask,idleEnd);
-  #endif
-  sleepTask=NULL;
-  active().dirty=true;
-  out.clear();
-}
-
-bool navNode::changed(const menuOut& out) const {
-  trace("navNode::changed");
-  if (out.drawn==NULL||target->changed(*this,out)) {
-    root->lastChanged=millis();
-    return true;
-  } else
-    if (root->canExit&&root->timeOut&&(millis()-root->lastChanged)/1000>root->timeOut)
-      root->idleOn(root->idleTask);
-  return false;
-}
-
-bool navRoot::changed(const menuOut& out) {
-  trace(MENU_DEBUG_OUT.println("DEBUG: changed"));
-  if (sleepTask) return idleChanged;
-  return node().changed(out);
-}
-
-
-#ifdef MENU_ASYNC
-// prompt* navRoot::seek(char* uri) {
-//   StringStream s(uri);
-//   size_t len = std::count(s.begin(), s.end(), '/');
-//   if (uri[0]=='/') s>>'/';  else len++;
-//   assert(len<(1<<(sizeof(idx_t)<<3)));
-//   idx_t sel[len];
-//   for(int n=0;n<len;n++) {
-//     s>>sel[n];
-//     s>>'/';
-//   }
-//   return seek(sel,len);
-// }
-// prompt* navRoot::seek(idx_t* uri,idx_t len) {
-//   trace(MENU_DEBUG_OUT<<"menuNode::seek"<<endl);
-//   if (len&&uri[0]>=0&&uri[0]<sz()) {
-//     prompt& e=operator[](uri[0]);
-//     assert(e.isMenu());
-//     return e.seek(++uri,--len);
-//   } else return NULL;
-// }
-idx_t navRoot::escTo(idx_t lvl) {
-  assert(lvl>=0);
-  // if (lvl<0) return;
-  idx_t cnt=0;
-  while(level>lvl) {
-    trace(MENU_DEBUG_OUT<<"escaping "<<level<<endl);
-    doNav(escCmd);
-    cnt++;
-  }
-  return cnt;
-}
-bool navRoot::async(const char* at) {
-  trace(MENU_DEBUG_OUT<<"navRoot::async "<<at<<endl);
-  if (!(at&&*at)||at[0]=='/')
-    return path[0].target->async(at, *this, 0);
-  else
-    return active().async(at, *this, level+1);//TODO: check max_depth here!
-}
-menuOut& navRoot::printPath(menuOut& o,menuNode* to) const {
-  trace(MENU_DEBUG_OUT<<"printPath:");
-  for(idx_t n=0;n<level&&path[n].target!=to;n++) {
-    o.print('/');
-    o.print(path[n].sel);
-  }
-  trace(MENU_DEBUG_OUT<<endl);
-  return o;
-}
-//async printMenu on arbitrary menuOut device
-Used navRoot::printMenu(menuOut& o) const {
-  trace(MENU_DEBUG_OUT<<"navRoot::printMenu(menuOut& o)"<<endl);
-  if ((active().sysStyles()&_parentDraw)&&level)
-    return o.printMenu(path[level-1]);
-  else return o.printMenu(node());
-}
-
-#endif
diff --git a/src/nav.h b/src/nav.h
deleted file mode 100644
index 3acd1862..00000000
--- a/src/nav.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/* -*- C++ -*- */
-#ifndef RSITE_ARDUINO_MENU_SYSTEM_NAV
-  #define RSITE_ARDUINO_MENU_SYSTEM_NAV
-  #include "menuBase.h"
-  #include "menuIo.h"
-  namespace Menu {
-
-    //navigation panels (min 1) describe output dimensions (in characters)
-    struct panel {
-      idx_t x,y,w,h;
-      inline idx_t maxX() const {return x+w;}
-      inline idx_t maxY() const {return y+h;}
-    };
-
-    //multiple panels
-    class panelsList {
-      public:
-        constMEM panel* panels;
-        navNode** nodes;
-        constMEM idx_t sz;
-        idx_t cur=0;
-        inline panelsList(constMEM panel p[],navNode* nodes[],idx_t sz):panels(p),nodes(nodes),sz(sz) {
-          reset();
-        }
-        void reset(idx_t from=0);
-        inline constMEM panel operator[](idx_t i) const {
-          // assert(i<sz);
-          #ifdef USING_PGM
-            panel tmp;
-            memcpy_P(&tmp, &panels[i], sizeof(panel));
-            return tmp;
-          #else
-            return panels[i];
-          #endif
-        }
-        idx_t maxX() const;
-        idx_t maxY() const;
-    };
-
-    // Navigation
-    //////////////////////////////////////////////////////////////////////////
-    class navNode {
-      friend class navRoot;
-      protected:
-        inline menuNodeShadow& shadow() const {return *(menuNodeShadow*)target->shadow;}
-        inline void useMenu(menuNode &menu) {target=&menu;reset();}
-      public:
-        idx_t sel=0;
-        menuNode* target;
-        /*static*/ navRoot* root;//v 4.0 removed static to allow multiple menus
-        inline void reset() {sel=0;}
-        inline idx_t sz() const {return target->sz();}
-        inline prompt* constMEM * data() const {return target->data();}
-        inline prompt& selected() const {return *(prompt*)memPtr(data()[sel]);}
-        inline bool wrap() const {return target->style()&wrapStyle;}
-        result event(eventMask e,idx_t i);//send event to item index i
-        inline result event(eventMask e) {return event(e,sel);}//send event to current item
-        result sysEvent(eventMask e,idx_t i);//send system event to item index i
-        inline result sysEvent(eventMask e) {return sysEvent(e,sel);}//send event to current item
-        navCmd navKeys(char ch);
-        navCmd doNavigation(navCmd cmd);//aux function
-        // inline int getPanelIdx(menuOut& out) const {return out.getPanelIdx(*this);}
-        bool changed(const menuOut& out) const;
-        inline prompt& operator[](idx_t i) const {return target->operator[](i);}
-
-        inline bool is(systemStyles chk)  const {return target->is(chk);}
-        inline bool has(systemStyles chk) const {return target->has(chk);}
-        inline bool is(styles chk)        const {return target->is(chk);}
-        inline bool has(styles chk)       const {return target->has(chk);}
-        inline bool is(eventMask chk)     const {return target->is(chk);}
-        inline bool has(eventMask chk)    const {return target->has(chk);}
-    };
-
-    class navRoot {
-      public:
-        outputsList &out;
-        menuIn& in;
-        navNode* path;
-        constMEM idx_t maxDepth=0;
-        idx_t level=0;
-        bool showTitle=true;
-        bool idleChanged=false;//does idle screen need refresh?
-        idleFunc idleTask=inaction;//to do when menu exits, menu system will set idleFunc to this on exit
-        idleFunc sleepTask=NULL;//menu suspended, call this function
-        navTarget* navFocus=NULL;
-        bool nav2D=false;
-        bool canExit=true;//v4.0 moved from global options
-        bool useUpdateEvent=false;//if false, when field value is changed use enterEvent instead.
-        idx_t inputBurst=1;//limit of inputs that can be processed before output
-        unsigned long lastChanged=0;//last change detected (can be external activity)
-        int timeOut=0;//enter idle mode after `timeOut` seconds of inactivity
-        bool useAccel=true;//use numeric accelerators to send idxCmd
-        inline navRoot(menuNode& root,navNode* path,idx_t d,menuIn& in,outputsList &o)
-          :out(o),in(in),path(path),maxDepth(d-1) {
-            useMenu(root);
-            initPath(d-1);
-          }
-        void initPath(idx_t d);
-        void useMenu(menuNode &menu);
-        inline void reset() {
-          level=0;
-          navFocus=path[level].target;
-          path[level].reset();
-          refresh();
-        }
-        inline void refresh() {out.refresh();}
-        inline navNode& node() const {return path[level];}
-        inline menuNode& active() const {return *node().target;}
-        inline prompt& selected() const {return active()[node().sel];}
-        bool changed(const menuOut& out);
-        inline bool changed(idx_t n) {return changed(out[n]);}
-        #ifdef MENU_ASYNC
-          idx_t escTo(idx_t lvl);
-          // prompt* seek(idx_t* uri,idx_t len);
-          bool async(const char* at);
-          menuOut& printPath(menuOut& o,menuNode*) const;
-          Used printMenu(menuOut& o) const;
-        #endif
-        Used printMenu() const;
-        //menu IO - external iteration functions
-        void doInput(menuIn& in);
-        #ifdef MENU_ASYNC
-          inline void doInput(const char*in) {
-            StringStream inStr(in);
-            while(inStr.available()) doInput(inStr);
-          }
-        #endif
-        inline void doInput() {doInput(in);}
-        void doOutput();
-        inline void poll() {doInput();doOutput();};//fire and forget mode
-        void doNav(navCmd cmd);//fly by wire mode
-        navCmd enter();//aux function
-        navCmd exit();//aux function
-
-        //enter idle mode ---------------------------------
-        void idleOn(idleFunc task=inaction);
-        void idleOff();
-    };
-
-    #ifdef MENU_DEBUG
-      inline Stream& operator<<(Stream&o,const navNode& p) {
-        o.print((__FlashStringHelper*)p.target->getText());
-        return o;
-      }
-      inline Stream& operator<<(Stream&o,const navRoot& p) {return o<<p.node();}
-    #endif
-
-  }//namespace Menu
-
-#endif
diff --git a/src/plugin/SDMenu.h b/src/plugin/SDMenu.h
deleted file mode 100644
index 217bb88d..00000000
--- a/src/plugin/SDMenu.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/* -*- C++ -*- */
-#pragma once
-// a full automated SDCard file select
-// plugin for arduino menu library
-// requires a dynamic menu (MENU_USERAM)
-// IO: Serial
-// Feb 2019 - Rui Azevedo [ruihfazevedo@gmail.com]
-#include <menu.h>
-
-using namespace Menu;
-
-//minimalist SD Card driver (using arduino SD)
-//we avoid allocating memory here, instead we read all info from SD
-template<typename SDC>
-class FSO {
-public:
-  using Type=SDC;
-  Type& sdc;
-  //idx_t selIdx=0;//preserve selection context, because we preserve folder ctx too
-  //we should use filename instead! idx is useful for delete operations thou...
-
-  File dir;
-
-  FSO(Type& sdc):sdc(sdc) {}
-  virtual ~FSO() {dir.close();}
-  //open a folder
-  bool goFolder(String folderName) {
-    dir.close();
-    // Serial.println("reopen dir, context");
-    dir=sdc.open(folderName.c_str());
-    return dir;
-  }
-  //count entries on folder (files and dirs)
-  long count() {
-    // Serial.print("count:");
-    dir.rewindDirectory();
-    int cnt=0;
-    while(true) {
-      File file=dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      file.close();
-      cnt++;
-    }
-    // Serial.println(cnt);
-    return cnt;
-  }
-
-  //get entry index by filename
-  long entryIdx(String name) {
-    dir.rewindDirectory();
-    int cnt=0;
-    while(true) {
-      File file=dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      if(name==file.name()) {
-        file.close();
-        return cnt;
-      }
-      file.close();
-      cnt++;
-    }
-    return 0;//stay at menu start if not found
-  }
-
-  //get folder content entry by index
-  String entry(long idx) {
-    dir.rewindDirectory();
-    idx_t cnt=0;
-    while(true) {
-      File file=dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      if(idx==cnt++) {
-        String n=String(file.name())+(file.isDirectory()?"/":"");
-        file.close();
-        return n;
-      }
-      file.close();
-    }
-    return "";
-  }
-
-};
-
-//////////////////////////////////////////////////////////////////////
-// SD Card cached menu
-template<typename SDC,idx_t maxSz>
-class CachedFSO:public FSO<SDC> {
-public:
-  using Type=SDC;
-  long cacheStart=0;
-  String cache[maxSz];
-  long size=0;//folder size (count of files and folders)
-  CachedFSO(Type& sdc):FSO<SDC>(sdc) {}
-  void refresh(long start=0) {
-    if (start<0) start=0;
-    // Serial.print("Refreshing from:");
-    // Serial.println(start);
-    cacheStart=start;
-    FSO<SDC>::dir.rewindDirectory();
-    size=0;
-    while(true) {
-      File file=FSO<SDC>::dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      if (start<=size&&size<start+maxSz)
-        cache[size-start]=String(file.name())+(file.isDirectory()?"/":"");
-      file.close();
-      size++;
-    }
-  }
-  //open a folder
-  bool goFolder(String folderName) {
-    if (!FSO<SDC>::goFolder(folderName)) return false;
-    refresh();
-    return true;
-  }
-  long count() {return size;}
-
-  long entryIdx(String name) {
-    idx_t sz=min(count(),(long)maxSz);
-    for(int i=0;i<sz;i++)
-      if (name==cache[i]) return i+cacheStart;
-    long at=FSO<SDC>::entryIdx(name);
-    //put cache around the missing item
-    refresh(at-(maxSz>>1));
-    return at;
-  }
-  String entry(long idx) {
-    if (0>idx||idx>=size) return "";
-    if (cacheStart<=idx&&idx<(cacheStart+maxSz)) return cache[idx-cacheStart];
-    refresh(idx-(maxSz>>1));
-    return entry(idx);
-  }
-};
-
-////////////////////////////////////////////////////////////////////////////
-#include <SD.h>
-// instead of allocating options for each file we will instead customize a menu
-// to print the files list, we can opt to use objects for each file for a
-// faster reopening.. but its working quite fast
-// On this example we assume the existence of an esc button as we are not drawing
-// an exit option (or [..] as would be appropriate for a file system)
-// not the mennu presents it self as the menu and as the options
-// ands does all drawing navigation.
-//TODO: we can specialize input too, for typing filename select
-  #define USE_BACKDOTS 1
-
-template<typename FS>
-class SDMenuT:public menuNode,public FS {
-public:
-  String folderName="/";//set this to other folder when needed
-  String selectedFolder="/";
-  String selectedFile="";
-  // using menuNode::menuNode;//do not use default constructors as we wont allocate for data
-  SDMenuT(typename FS::Type& sd,constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
-    :menuNode(title,0,NULL,act,mask,
-      wrapStyle,(systemStyles)(_menuData|_canNav))
-    ,FS(sd)
-    {}
-
-  void begin() {FS::goFolder(folderName);}
-
-  //this requires latest menu version to virtualize data tables
-  prompt& operator[](idx_t i) const override {return *(prompt*)this;}//this will serve both as menu and as its own prompt
-  result sysHandler(SYS_FUNC_PARAMS) override {
-    switch(event) {
-      case enterEvent:
-        if (nav.root->navFocus!=nav.target) {//on sd card entry
-          nav.sel=((SDMenuT<FS>*)(&item))->entryIdx(((SDMenuT<FS>*)(&item))->selectedFile)+USE_BACKDOTS;//restore context
-        }
-    }
-    return proceed;
-  }
-
-  void doNav(navNode& nav,navCmd cmd) {
-    switch(cmd.cmd) {
-      case enterCmd: if (nav.sel>=USE_BACKDOTS) {
-          String selFile=SDMenuT<FS>::entry(nav.sel-USE_BACKDOTS);
-          if (selFile.endsWith("/")) {
-            // Serial.print("\nOpen folder...");
-            //open folder (reusing the menu)
-            folderName+=selFile;
-            SDMenuT<FS>::goFolder(folderName);
-            dirty=true;//redraw menu
-            nav.sel=0;
-          } else {
-            //Serial.print("\nFile selected:");
-            //select a file and return
-            selectedFile=selFile;
-            selectedFolder=folderName;
-            nav.root->node().event(enterEvent);
-            menuNode::doNav(nav,escCmd);
-          }
-          return;
-        }
-      case escCmd:
-        if(folderName=="/")//at root?
-          menuNode::doNav(nav,escCmd);//then exit
-        else {//previous folder
-          idx_t at=folderName.lastIndexOf("/",folderName.length()-2)+1;
-          String fn=folderName.substring(at,folderName.length()-1);
-          folderName.remove(folderName.lastIndexOf("/",folderName.length()-2)+1);
-          SDMenuT<FS>::goFolder(folderName);
-          dirty=true;//redraw menu
-          nav.sel=SDMenuT<FS>::entryIdx(fn)+USE_BACKDOTS;
-        }
-        return;
-    }
-    menuNode::doNav(nav,cmd);
-  }
-
-  //print menu and items as this is a virtual data menu
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t pn) {
-    if(root.navFocus!=this) {//show given title or filename if selected
-      return selectedFile==""?
-        menuNode::printTo(root,sel,out,idx,len,pn):
-        out.printRaw(selectedFile.c_str(),len);
-    } else if(idx==-1) {//when menu open (show folder name)
-      ((menuNodeShadow*)shadow)->sz=SDMenuT<FS>::count()+USE_BACKDOTS;
-      idx_t at=folderName.lastIndexOf("/",folderName.length()-2)+1;
-      String fn=folderName.substring(at,folderName.length()-1);
-      return out.printRaw(fn.c_str(),len);
-      // return out.printRaw(folderName.c_str(),len);
-      // return out.printRaw(SDMenuT<FS>::dir.name(),len);
-    }
-    //drawing options
-    idx_t i=out.tops[root.level]+idx;
-    if (i<USE_BACKDOTS) len-=out.printRaw("[..]",len);
-    else len-=out.printRaw(SDMenuT<FS>::entry(out.tops[root.level]+idx-USE_BACKDOTS).c_str(),len);
-    return len;
-  }
-};
-
-class SDMenu:public SDMenuT<FSO<decltype(SD)>> {
-public:
-  SDMenu(constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
-    :SDMenuT<FSO<decltype(SD)>>(SD,title,at,act,mask) {}
-};
-
-template<idx_t cacheSize>
-class CachedSDMenu:public SDMenuT<CachedFSO<decltype(SD),cacheSize>> {
-public:
-  CachedSDMenu(constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
-    :SDMenuT<CachedFSO<decltype(SD),cacheSize>>(SD,title,at,act,mask) {}
-};
diff --git a/src/plugin/SdFatMenu.h b/src/plugin/SdFatMenu.h
deleted file mode 100644
index 94b3b43d..00000000
--- a/src/plugin/SdFatMenu.h
+++ /dev/null
@@ -1,267 +0,0 @@
-/* -*- C++ -*- */
-#pragma once
-// a full automated SDCard file select
-// plugin for arduino menu library
-// requires a dynamic menu (MENU_USERAM)
-// IO: Serial
-// Feb 2019 - Rui Azevedo [ruihfazevedo@gmail.com]
-
-//using SdFat library
-//from: https://github.com/greiman/SdFat
-
-#include <menu.h>
-
-using namespace Menu;
-
-#define FN_SIZE 255
-
-//minimalist SD Card driver (using arduino SD)
-//we avoid allocating memory here, instead we read all info from SD
-template<typename SDC,int fnSize=FN_SIZE>
-class FSO {
-public:
-  char fname[FN_SIZE+1];
-  using Type=SDC;
-  Type& sdc;
-  //idx_t selIdx=0;//preserve selection context, because we preserve folder ctx too
-  //we should use filename instead! idx is useful for delete operations thou...
-
-  File dir;
-
-  FSO(Type& sdc):sdc(sdc) {}
-  virtual ~FSO() {dir.close();}
-  //get file name
-  //open a folder
-  bool goFolder(String folderName) {
-    dir.close();
-    // Serial.println("reopen dir, context");
-    dir=sdc.open(folderName.c_str());
-    return dir;
-  }
-  //count entries on folder (files and dirs)
-  long count() {
-    // Serial.print("count:");
-    dir.rewindDirectory();
-    int cnt=0;
-    while(true) {
-      File file=dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      file.close();
-      cnt++;
-    }
-    // Serial.println(cnt);
-    return cnt;
-  }
-
-  //get entry index by filename
-  long entryIdx(String name) {
-    dir.rewindDirectory();
-    int cnt=0;
-    while(true) {
-      File file=dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      if(file.getName(fname,fnSize)&&name==fname) {
-        file.close();
-        return cnt;
-      }
-      file.close();
-      cnt++;
-    }
-    return 0;//stay at menu start if not found
-  }
-
-  //get folder content entry by index
-  String entry(long idx) {
-    dir.rewindDirectory();
-    idx_t cnt=0;
-    while(true) {
-      File file=dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      if(idx==cnt++) {
-        file.getName(fname,fnSize);
-        String n=String(fname)+(file.isDirectory()?"/":"");
-        file.close();
-        return n;
-      }
-      file.close();
-    }
-    return "";
-  }
-
-};
-
-//////////////////////////////////////////////////////////////////////
-// SD Card cached menu
-template<typename SDC,idx_t maxSz,int fnSize=FN_SIZE>
-class CachedFSO:public FSO<SDC,fnSize> {
-public:
-  using Type=SDC;
-  long cacheStart=0;
-  String cache[maxSz];
-  long size=0;//folder size (count of files and folders)
-  CachedFSO(Type& sdc):FSO<SDC>(sdc) {}
-  void refresh(long start=0) {
-    if (start<0) start=0;
-    // Serial.print("Refreshing from:");
-    // Serial.println(start);
-    cacheStart=start;
-    FSO<SDC>::dir.rewindDirectory();
-    size=0;
-    while(true) {
-      File file=FSO<SDC>::dir.openNextFile();
-      if (!file) {
-        file.close();
-        break;
-      }
-      if (start<=size&&size<start+maxSz) {
-        file.getName(FSO<SDC>::fname,fnSize);
-        cache[size-start]=String(FSO<SDC>::fname)+(file.isDirectory()?"/":"");
-      }
-      file.close();
-      size++;
-    }
-  }
-  //open a folder
-  bool goFolder(String folderName) {
-    if (!FSO<SDC>::goFolder(folderName)) return false;
-    refresh();
-    return true;
-  }
-  long count() {return size;}
-
-  long entryIdx(String name) {
-    idx_t sz=min(count(),(long)maxSz);
-    for(int i=0;i<sz;i++)
-      if (name==cache[i]) return i+cacheStart;
-    long at=FSO<SDC>::entryIdx(name);
-    //put cache around the missing item
-    refresh(at-(maxSz>>1));
-    return at;
-  }
-  String entry(long idx) {
-    if (0>idx||idx>=size) return "";
-    if (cacheStart<=idx&&idx<(cacheStart+maxSz)) return cache[idx-cacheStart];
-    refresh(idx-(maxSz>>1));
-    return entry(idx);
-  }
-};
-
-////////////////////////////////////////////////////////////////////////////
-#include <SdFat.h>
-// instead of allocating options for each file we will instead customize a menu
-// to print the files list, we can opt to use objects for each file for a
-// faster reopening.. but its working quite fast
-// On this example we assume the existence of an esc button as we are not drawing
-// an exit option (or [..] as would be appropriate for a file system)
-// not the mennu presents it self as the menu and as the options
-// ands does all drawing navigation.
-//TODO: we can specialize input too, for typing filename select
-  #define USE_BACKDOTS 1
-
-template<typename FS>
-class SDMenuT:public menuNode,public FS {
-public:
-  String folderName="/";//set this to other folder when needed
-  String selectedFolder="/";
-  String selectedFile="";
-  // using menuNode::menuNode;//do not use default constructors as we wont allocate for data
-  SDMenuT(typename FS::Type& sd,constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
-    :menuNode(title,0,NULL,act,mask,
-      wrapStyle,(systemStyles)(_menuData|_canNav))
-    ,FS(sd)
-    {}
-
-  void begin() {FS::goFolder(folderName);}
-
-  //this requires latest menu version to virtualize data tables
-  prompt& operator[](idx_t i) const override {return *(prompt*)this;}//this will serve both as menu and as its own prompt
-  result sysHandler(SYS_FUNC_PARAMS) override {
-    switch(event) {
-      case enterEvent:
-        if (nav.root->navFocus!=nav.target) {//on sd card entry
-          nav.sel=((SDMenuT<FS>*)(&item))->entryIdx(((SDMenuT<FS>*)(&item))->selectedFile)+USE_BACKDOTS;//restore context
-        }
-    }
-    return proceed;
-  }
-
-  void doNav(navNode& nav,navCmd cmd) {
-    switch(cmd.cmd) {
-      case enterCmd: if (nav.sel>=USE_BACKDOTS) {
-          String selFile=SDMenuT<FS>::entry(nav.sel-USE_BACKDOTS);
-          if (selFile.endsWith("/")) {
-            // Serial.print("\nOpen folder...");
-            //open folder (reusing the menu)
-            folderName+=selFile;
-            SDMenuT<FS>::goFolder(folderName);
-            dirty=true;//redraw menu
-            nav.sel=0;
-          } else {
-            //Serial.print("\nFile selected:");
-            //select a file and return
-            selectedFile=selFile;
-            selectedFolder=folderName;
-            nav.root->node().event(enterEvent);
-            menuNode::doNav(nav,escCmd);
-          }
-          return;
-        }
-      case escCmd:
-        if(folderName=="/")//at root?
-          menuNode::doNav(nav,escCmd);//then exit
-        else {//previous folder
-          idx_t at=folderName.lastIndexOf("/",folderName.length()-2)+1;
-          String fn=folderName.substring(at,folderName.length()-1);
-          folderName.remove(folderName.lastIndexOf("/",folderName.length()-2)+1);
-          SDMenuT<FS>::goFolder(folderName);
-          dirty=true;//redraw menu
-          nav.sel=SDMenuT<FS>::entryIdx(fn)+USE_BACKDOTS;
-        }
-        return;
-    }
-    menuNode::doNav(nav,cmd);
-  }
-
-  //print menu and items as this is a virtual data menu
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t pn) {
-    if(root.navFocus!=this) {//show given title or filename if selected
-      return selectedFile==""?
-        menuNode::printTo(root,sel,out,idx,len,pn):
-        out.printRaw(selectedFile.c_str(),len);
-    } else if(idx==-1) {//when menu open (show folder name)
-      ((menuNodeShadow*)shadow)->sz=SDMenuT<FS>::count()+USE_BACKDOTS;
-      idx_t at=folderName.lastIndexOf("/",folderName.length()-2)+1;
-      String fn=folderName.substring(at,folderName.length()-1);
-      return out.printRaw(fn.c_str(),len);
-      // return out.printRaw(folderName.c_str(),len);
-      // return out.printRaw(SDMenuT<FS>::dir.name(),len);
-    }
-    //drawing options
-    idx_t i=out.tops[root.level]+idx;
-    if (i<USE_BACKDOTS) len-=out.printRaw("[..]",len);
-    else len-=out.printRaw(SDMenuT<FS>::entry(out.tops[root.level]+idx-USE_BACKDOTS).c_str(),len);
-    return len;
-  }
-};
-
-// class SDMenu:public SDMenuT<FSO<decltype(SdFat)>> {
-// public:
-//   SDMenu(SdFat& sd,constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
-//     :SDMenuT<FSO<decltype(SdFat)>>(SD,title,at,act,mask) {}
-// };
-//
-// template<idx_t cacheSize>
-// class CachedSDMenu:public SDMenuT<CachedFSO<decltype(SdFat),cacheSize>> {
-// public:
-//   CachedSDMenu(constText* title,const char* at,Menu::action act=doNothing,Menu::eventMask mask=noEvent)
-//     :SDMenuT<CachedFSO<decltype(SdFat),cacheSize>>(SD,title,at,act,mask) {}
-// };
diff --git a/src/plugin/barField.cpp b/src/plugin/barField.cpp
deleted file mode 100644
index 8c1b607f..00000000
--- a/src/plugin/barField.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "barField.h"
-
-using namespace Menu;
-
-const char* barFieldOptions::fill="|";
-const char* barFieldOptions::empty="-";
diff --git a/src/plugin/barField.h b/src/plugin/barField.h
deleted file mode 100644
index c5ee2aab..00000000
--- a/src/plugin/barField.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- C++ -*- */
-/********************
-May 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-
-www.r-site.net
-
-custom field edit (experimental)
-this edit is an example of a navTarget element ,
-nomally drawn as part of the parent (inplace edit)
-being draw on its own screen (quite radical change)
-the element still draws inline when not editing
-
-the ideal of settings would be by output device
-and as functions instead of data
-...
-
-eventually on this schema plugins will speciallize on device types
-but hopefully simpler to write
-
-use it as:
-
-altFIELD(barField,...)
-
-or
-
-BARFIELD(...)
-
-the remaining parameters are the same as the regular FIELD
-
-***/
-
-#ifndef RSITE_ARDUINO_MENU_BAR_FIELD
-  #define RSITE_ARDUINO_MENU_BAR_FIELD
-
-#include "../menuDefs.h"
-#include "cancelField.h"
-
-using namespace Menu;
-
-#define BARFIELD(...) altFIELD(barField,__VA_ARGS__)
-
-class barFieldOptions {
-public:
-  //these are made string to allow unicode,
-  //BUT you should only provide ONE character
-  //otherwise stuff will overflow!
-  static const char* fill;
-  static const char* empty;
-};
-
-template<typename T>
-class barField:public cancelField<T>,public barFieldOptions {
-public:
-  barField(constMEM menuFieldShadow<T>& shadow):cancelField<T>(shadow) {}
-  Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr=0) override {
-    bool ed=this==root.navFocus;
-    if (ed) {
-      //out.clear();
-      out.clearLine(0);
-      out.setCursor(0,0);
-      if (out.maxX()>1) {
-        cancelField<T>::printTo(root,sel,out,idx,len);
-        out.clearLine(1);
-        out.setCursor(0,1);
-      }
-      int bar=map(menuField<T>::target(),menuField<T>::low(),menuField<T>::high(),0,out.maxX());
-      for (int n=0;n<bar;n++) out.print(fill);
-      for (int n=bar;n<out.maxX();n++) out.print(empty);
-      return 0;
-    } else return cancelField<T>::printTo(root,sel,out,idx,len);
-  }
-};
-
-#endif
diff --git a/src/plugin/cancelField.cpp b/src/plugin/cancelField.cpp
deleted file mode 100644
index 551faf02..00000000
--- a/src/plugin/cancelField.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "cancelField.h"
-
-bool cancelFieldOptions::quitOnEsc=true;
-bool cancelFieldOptions::accelSendEsc=true;
diff --git a/src/plugin/cancelField.h b/src/plugin/cancelField.h
deleted file mode 100644
index 18e858ce..00000000
--- a/src/plugin/cancelField.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- C++ -*- */
-/********************
-May 2017 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
-www.r-site.net
-
-implementing a cancelable field
-this field restores the original value on escape
-
-use it as:
-
-altFIELD(cancelField,...);
-
-the remaining parameters are the same as the regular FIELD
-
-***/
-
-#ifndef RSITE_ARDUINO_MENU_CANCEL_FIELD
-  #define RSITE_ARDUINO_MENU_CANCEL_FIELD
-
-#include "../menuDefs.h"
-
-using namespace Menu;
-
-class cancelFieldOptions {
-public:
-  static bool quitOnEsc;
-  static bool accelSendEsc;
-};
-
-//custom field edit
-template<typename T>
-class cancelField:public menuField<T> {
-public:
-  T original;//to use when canceling
-  bool editing;
-  cancelField(constMEM menuFieldShadow<T>& shadow):menuField<T>(shadow),editing(false) {}
-  void doNav(navNode& nav,navCmd cmd) override {
-    if (!editing) {
-      original=menuField<T>::target();
-      editing=true;
-    }
-    switch(cmd.cmd) {
-      case selCmd:
-      case idxCmd:
-        //MENU_DEBUG_OUT<<"IDX"<<endl;
-        menuField<T>::tunning=true;//prepare for exit
-        return doNav(nav,cancelFieldOptions::accelSendEsc?escCmd:enterCmd);
-      case escCmd:
-        editing=!cancelFieldOptions::quitOnEsc;
-        //menuField<T>::tunning=false;
-        //MENU_DEBUG_OUT<<"ESC"<<endl;
-        menuField<T>::target()=original;
-        break;
-      case enterCmd:
-        //MENU_DEBUG_OUT<<"ENTER"<<endl;
-        if (menuField<T>::tunning||nav.root->nav2D||!menuField<T>::tune())
-          editing=false;
-        break;
-      default: break;
-    }
-    menuField<T>::doNav(nav,cmd);
-  }
-};
-
-#endif
diff --git a/src/shadows.h b/src/shadows.h
deleted file mode 100644
index 98d48d0c..00000000
--- a/src/shadows.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/* -*- C++ -*- */
-
-#ifndef RSITE_ARDUINO_MENU_SHADOWS
-  #define RSITE_ARDUINO_MENU_SHADOWS
-
-  #include "menuBase.h"
-
-  namespace Menu {
-
-    struct promptShadowRaw {
-      actionRaw a;//the hooked callback function
-      systemStyles sysStyles;
-      constText*text;
-      constMEM eventMask events;//registered events
-      styles style;
-    };
-    class promptShadow:public action {
-      protected:
-      public:
-        systemStyles sysStyles;
-        constText*text;
-        eventMask events;//registered events (mask)
-        styles style;
-      public:
-        promptShadow(constText* t,action a=doNothing,eventMask e=noEvent,styles s=noStyle,systemStyles ss=_noStyle)
-          :action(a),sysStyles(ss),text(t),events(e),style(s) {}
-        inline constText* getText() const {return (constText*)memPtr(text);}
-        inline systemStyles _sysStyles() const {return (systemStyles)memEnum(&sysStyles);}
-        inline eventMask _events() const {return (eventMask)memEnum(&events);}
-        inline styles _style() const {return (styles)memEnum(&style);}
-    };
-    struct textFieldShadowRaw {
-      actionRaw a;
-      systemStyles sysStyles;
-      constText*text;
-      eventMask events;//registered events
-      styles style;
-      char* buffer;
-      char* const* validators;
-      idx_t sz;
-    };
-    class textFieldShadow:public promptShadow {
-      protected:
-      public:
-        char* buffer;
-        char* const* validators;
-        idx_t sz;
-        textFieldShadow(
-          constText* label,
-          char* b,
-          idx_t sz,
-          char* const* v,
-          action a=doNothing,
-          eventMask e=noEvent,
-          styles style=noStyle,
-          systemStyles ss=(Menu::systemStyles)(_noStyle|_canNav|_parentDraw)
-        ):promptShadow(label,a,e,style,ss),buffer(b),validators(v),sz(sz) {}
-        idx_t _sz() const {return (idx_t)memIdx(sz);}
-        char* _buffer() const {return (char*)memPtr(buffer);}
-        char* const* _validators() const {return (char* const*)memPtr(validators);}
-        inline constText* operator[](idx_t i) const {
-          return (char*)memPtr(((char**)_validators())[i]);
-        }
-    };
-    struct menuNodeShadowRaw {
-      actionRaw a;
-      systemStyles sysStyles;
-      constText*text;
-      eventMask events;//registered events
-      styles style;
-      idx_t sz;
-      prompt* constMEM* data;
-    };
-    class menuNodeShadow:public promptShadow {
-      protected:
-      public:
-        idx_t sz;
-        prompt* constMEM* data;
-      public:
-        menuNodeShadow(constText* text,idx_t sz,prompt* constMEM* data,action a,eventMask e,styles style,systemStyles ss=(systemStyles)(_menuData|_canNav))
-        :promptShadow(text,a,e,style,ss),sz(sz),data(data) {}
-        idx_t _sz() const {return (idx_t)memIdx(sz);}
-        prompt* constMEM* _data() const {return (prompt* constMEM*)memPtr(data);}
-        inline prompt& operator[](idx_t i) const {
-          return *(prompt*)memPtr(((prompt**)_data())[i]);
-          //return *(prompt*)memPtr(((prompt**)memPtr(((menuNodeShadow*)shadow)->data))[i]);
-        }
-    };
-
-    struct fieldBaseShadowRaw {
-      actionRaw a;
-      systemStyles sysStyles;
-      constText*text;
-      eventMask events;//registered events
-      styles style;
-      constText* units;
-    };
-    class fieldBaseShadow:public promptShadow {
-      public:
-        constText* units;
-        fieldBaseShadow(constText* text,constText*units,action a=doNothing,eventMask e=noEvent,styles s=noStyle,systemStyles ss=((Menu::systemStyles)(Menu::_canNav|Menu::_parentDraw)))
-          :promptShadow(text,a,e,s,ss),units(units) {}
-        inline constText* _units() {return (constText*)memPtr(units);}
-    };
-    template<typename T>
-    struct menuFieldShadowRaw {
-      actionRaw a;
-      systemStyles sysStyles;
-      constText*text;
-      eventMask events;//registered events
-      styles style;
-      constText* units;
-      T* value;
-      constMEM T low,high,step,tune;
-    };
-    template<typename T>
-    class menuFieldShadow:public fieldBaseShadow {
-      protected:
-      public:
-        T* value;
-        constMEM T low,high,step,tune;
-      public:
-        menuFieldShadow(T &value,constText* text,constText*units,T low,T high,T step,T tune,action a=doNothing,eventMask e=noEvent,styles s=noStyle,systemStyles ss=((Menu::systemStyles)(Menu::_canNav|Menu::_parentDraw)))
-          :fieldBaseShadow(text,units,a,e,s,ss),value(&value),low(low),high(high),step(step),tune(tune) {}
-        inline T& target() const {return *(T*)memPtr(value);}
-        inline T getTypeValue(const T* from) const {
-          //TODO: dynamic versions require change of preprocessor to virtual
-          #ifdef USING_PGM
-            T tmp;
-            memcpy_P(&tmp, from, sizeof(T));
-            return tmp;
-          #else
-            return *from;
-          #endif
-        }
-        inline T _low() const {return getTypeValue(&low);}
-        inline T _high() const {return getTypeValue(&high);}
-        inline T _step() const {return getTypeValue(&step);}
-        inline T _tune() const {return  getTypeValue(&tune);}
-    };
-
-    template<typename T>
-    struct menuValueShadowRaw {
-      actionRaw a;
-      systemStyles sysStyles;
-      constText*text;
-      eventMask events;//registered events
-      styles style;
-      T value;
-    };
-    template<typename T>
-    class menuValueShadow:public promptShadow {
-      protected:
-      public:
-        T value;
-      public:
-        inline menuValueShadow(constText* text,T value,action a=doNothing,eventMask e=noEvent)
-          :promptShadow(text,a,e),value(value) {}
-        inline T getTypeValue(const T* from) const {
-          //TODO: dynamic versions require change of preprocessor to virtual
-          #ifdef USING_PGM
-            T tmp;
-            memcpy_P(&tmp, from, sizeof(T));
-            return tmp;
-          #else
-            return *from;
-          #endif
-        }
-        inline T target() const {return getTypeValue(&value);}
-    };
-
-    template<typename T>
-    struct menuVariantShadowRaw {
-      actionRaw a;
-      systemStyles sysStyles;
-      constText*text;
-      constMEM eventMask events;//registered events
-      styles style;
-      idx_t sz;
-      prompt* constMEM* data;
-      //int width;//field or menu width
-      //int ox,oy;//coordinate origin displacement
-      T* value;
-    };
-    template<typename T>
-    class menuVariantShadow:public menuNodeShadow {
-      public:
-        T* value;
-        menuVariantShadow(
-          constText* text,
-          T &target,
-          idx_t sz,
-          prompt* constMEM* data,
-          action a,
-          eventMask e,
-          styles style,
-          systemStyles ss=(systemStyles)(_menuData|_canNav)
-        ):menuNodeShadow(text,sz,data,a,e,style,ss),value(&target) {}
-      inline T& target() const {return *((T*)memPtr(value));}
-    };
-  }//namespace Menu
-#endif
diff --git a/test.json b/test.json
deleted file mode 100644
index 1a448f67..00000000
--- a/test.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "output":"",
-  "menu":{"title":{"prompt":"Einstellungen"},
-  ,"sel":"0","items":[
-{"idx":"0","enabled":"1","selStart":">""prompt":"Standby" ,"field":"5","range":{"low":"2","high":"5","step":"1","tune":"0"},"unit":"min."},
-{"idx":"1","enabled":"1","selStart":" ""prompt":"Key" ,"text":"QUYxMkJH"
-},
-{"idx":"2","enabled":"1","selStart":" ""prompt":"Mondlicht" ,"type":"select"",options":["Aus","#1","#2","#3","#4","#5","#6"]#4},
-{"idx":"3","enabled":"1","selStart":" ""prompt":"max" ,"field":"1","range":{"low":"0","high":"100","step":"10","tune":"1"},"unit":"%"},
-{"idx":"4","enabled":"1","selStart":" ""prompt":"Wolken:","value":"Aus",options":["Aus","An"]},
-{"idx":"5","enabled":"1","selStart":" ""prompt":"max" ,"field":"50","range":{"low":"0","high":"100","step":"10","tune":"1"},"unit":"%"},
-{"idx":"6","enabled":"1","selStart":" ""prompt":"Gewitter:","value":"Aus",options":["Aus","An"]},
-{"idx":"7","enabled":"1","selStart":" ""prompt":"max" ,"field":"50","range":{"low":"0","high":"100","step":"10","tune":"1"},"unit":"%"},
-{"idx":"8","enabled":"1","selStart":" ""prompt":"Wi-Fi"},
-{"idx":"9","enabled":"1","selStart":" ""prompt":"Sprache" ,"type":"select"",options":["DE","EN","PT"]DE},
-{"idx":"10","enabled":"1","selStart":" ""prompt":"Aktualisieren..."},
-{"idx":"11","enabled":"1","selStart":" ""prompt":"Speichern"},
-{"idx":"12","enabled":"1","selStart":" ""prompt":"Zurück"}
-]
-}
-}
diff --git a/tinyTimeUtils b/tinyTimeUtils
new file mode 160000
index 00000000..73cdc110
--- /dev/null
+++ b/tinyTimeUtils
@@ -0,0 +1 @@
+Subproject commit 73cdc1102768d601391821da23896e0b7ed2e947
